<p dir="auto">Is there anyone else out there using Playwright to test Power BI visuals? I didn't find anyone in the Power BI community doing it. I need to be able to click a value in a visual to adjust other visuals (&amp; "get" values); right click to show a drop down to drill through to another report that has additional values and table attributes. Can playwright be used to accomplish these tasks?</p>
<p dir="auto">I found a public visual that seems to have the same table attributes. If I can get it working for it then I should be able to do the same for our internal website reports. I used this public visual for my example code I have tried below.</p>
<p dir="auto">Here are the sections for a single element. It would be best if I can "find" / "click" / and "get" by the actual name "Weimei Corp" instead of all of the nth elements.  Also this report has way more frames than mine. I am able to get it to display the frame details. Is there documentation that shows each of these are broken down on how to get what I need by using the frame attributes?</p>
<p dir="auto">For the examples, I figured it should be from frame and not page but I would try both.</p>
<p dir="auto"><strong>Copy Element</strong></p>
<div title="Weimei Corp" dir="auto">Weimei Corp</div>
<p dir="auto"><strong>Copy Selector</strong><br>
#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)</p>
<p dir="auto"><strong>Copy JS Path</strong><br>
document.querySelector("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)")</p>
<p dir="auto"><strong>Copy XPath</strong><br>
//*[<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/id/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/id">@id</a>="pvExplorationHost"]/div/div/exploration/div/explore-canvas-modern/div/div[2]/div/div[2]/div[2]/visual-container-repeat/visual-container-modern[13]/transform/div/div[3]/div/visual-modern/div/div/div[2]/div[1]/div[4]/div/div/div[1]/div[5]</p>
<p dir="auto">Here is the code using that public visual and example codes I have tried to just click the "Weimei Corp"<br>
const playwright = require("playwright");</p>
<p dir="auto">(async function(){<br>
const browser = await playwright.chromium.launch({ headless: false , slowMo: 100 }); // Non-headless mode to feel comfy</p>
<p dir="auto">const context = await browser.newContext(); // So much to say, but another time<br>
const page = await context.newPage(); // Create a new Page instance which handles most of your needs</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await Promise.all([
  page.waitForNavigation(),
  page.goto('https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893')
]);
    
await page.waitForTimeout(30000); // wait for the Apps to load"><pre class="notranslate"><code class="notranslate">await Promise.all([
  page.waitForNavigation(),
  page.goto('https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893')
]);
    
await page.waitForTimeout(30000); // wait for the Apps to load
</code></pre></div>
<p dir="auto">debugger;</p>
<p dir="auto">console.log('start');</p>
<p dir="auto">console.log('Report is displayed');</p>
<p dir="auto">await page.frames().find((frame) =&gt; {<br>
console.log(frame,frame.name());<br>
return frame.name() === 'visual-sandbox'<br>
});<br>
console.log('Got visual-sandbox');</p>
<p dir="auto">//locate the iframe name visual sandbox<br>
const frame = page.frames().find(frame =&gt; frame.name() === 'visual-sandbox');<br>
console.log(frame.name());</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="console.log('Got visual-sandbox');
const title= await frame.title();
await console.log('title is:'+title);

await frame.waitForTimeout(10000);"><pre class="notranslate"><code class="notranslate">console.log('Got visual-sandbox');
const title= await frame.title();
await console.log('title is:'+title);

await frame.waitForTimeout(10000);
</code></pre></div>
<p dir="auto">// below doesn't work<br>
await page.click('text="Weimei Corp"');<br>
await frame.click('text="Weimei Corp"');</p>
<p dir="auto">//Error: Evaluation failed: TypeError: Cannot read property 'click' of null<br>
const corp = await page.evaluate(() =&gt; document.querySelector("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)").click());</p>
<p dir="auto">console.log('got Corp click ');</p>
<p dir="auto">// Error: Evaluation failed: TypeError: Cannot read property 'innerText' of null<br>
const fullText = await frame.evaluate(el =&gt; el.innerText, await page.$("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)"))<br>
//console.log(fullText)</p>
<p dir="auto">//TypeError: Cannot read property 'inntertext' of null<br>
//const hrefElement = await page.$('#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)');<br>
console.log(hrefElement.innerText.name);<br>
await hrefElement.click();</p>
<p dir="auto">//(node:10080) UnhandledPromiseRejectionWarning: Error: Error: failed to find element matching selector "#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)"<br>
//    at Frame._$evalExpression<br>
const hrefElement = await frame.$eval('#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)', el =&gt; el.value);<br>
console.log(hrefElement);<br>
await hrefElement.click();</p>
<p dir="auto">//(node:21332) UnhandledPromiseRejectionWarning: Error: page.waitForFunction: Evaluation failed: TypeError: Cannot read property 'length' of null<br>
await frame.waitForFunction(() =&gt; {<br>
const searches = document.querySelector(".pivotTableCellWrap cell-interactive tablixAlignLeft");<br>
console.log('found table');<br>
return searches.length &gt; 1;<br>
});<br>
await frame.waitForTimeout(10000);</p>
<p dir="auto">await frame.waitForFunction(() =&gt; {<br>
const searches = document.getElementsByClassName(".pivotTableCellWrap cell-interactive tablixAlignLeft");<br>
console.log('found table');<br>
return searches.length &gt; 1;<br>
});<br>
await frame.waitForTimeout(10000);</p>
<p dir="auto">//assert is not defined<br>
//const datatext = await page.$$eval('#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(5)',</p>
<p dir="auto">elements =&gt; elements.map(el =&gt; el.textContent.trim().split('\n')[0]))<br>
assert(datatext.length &gt; 0)</p>
<p dir="auto">//Error: Evaluation failed: TypeError: Cannot read property 'getAttribute' of undefined<br>
const myElem = await frame.evaluate(el =&gt; el.getAttribute('Weimei Corp'));<br>
console.log(myElem)</p>
<p dir="auto">const element = await page.$('#pvExplorationHost');</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await page.waitForFunction(() =&gt; {
  const searches = document.querySelectorAll('div.tableEx');
  console.log('found table');
  return searches.length &gt; 1;
});"><pre class="notranslate"><code class="notranslate">await page.waitForFunction(() =&gt; {
  const searches = document.querySelectorAll('div.tableEx');
  console.log('found table');
  return searches.length &gt; 1;
});
</code></pre></div>
<p dir="auto">await browser.close(); // Close the browser</p>
<p dir="auto">})();</p>
<p dir="auto">Here is example of values from my visual which is almost the same except if by title "THERESA WADE" has the special characters. I have also attached some screen shots for visual reference.</p>
<p dir="auto">"COPY ELEMENT"</p>
<div title="THERESA Z WADE" dir="auto">THERESA Z WADE</div>
<p dir="auto">"COPY SELECTOR"<br>
#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(3) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div:nth-child(1) &gt; div:nth-child(1) &gt; div:nth-child(1)<br>
#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(3) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div</p>
<p dir="auto">"Copy JS Path"<br>
document.querySelector("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(3) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div")</p>
<p dir="auto">"Copy XPath"<br>
//*[<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/id/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/id">@id</a>="pvExplorationHost"]/div/div/exploration/div/explore-canvas-modern/div/div[2]/div/div[2]/div[2]/visual-container-repeat/visual-container-modern[3]/transform/div/div[3]/div/visual-modern/div/div/div[2]/div[1]/div[4]/div/div/div[1]/div</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/71278576/93372739-e9e21480-f819-11ea-8ef4-ab343b95ff0e.JPG"><img src="https://user-images.githubusercontent.com/71278576/93372739-e9e21480-f819-11ea-8ef4-ab343b95ff0e.JPG" alt="publicreport" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/71278576/93372743-eb134180-f819-11ea-830b-4f49dce1e247.JPG"><img src="https://user-images.githubusercontent.com/71278576/93372743-eb134180-f819-11ea-830b-4f49dce1e247.JPG" alt="dropdown" style="max-width: 100%;"></a></p>
<p dir="auto">I have been at this for about 4 weeks with very little luck. I can't find where anyone else is using playwright to manipulate a Power BI report like a user. Can this be done?</p>
<p dir="auto">Currently unable to reference elements in a visual.  For a single cell the select value is very long.</p>
<p dir="auto">//doing this I get Error: Evaluation failed: TypeError: Cannot read property 'click' of null<br>
const corp = await frame.evaluate(() =&gt; document.querySelector("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(4)").click());</p>
<p dir="auto">I tried to do a for each but not sure how to verify the "elements" array was populated with data with the<br>
TypeError: Cannot read property 'click' of undefined</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="await frame.evaluate(() =&gt; {

  const elements = $('.pivotTableCellWrap cell-interactive tablixAlignLeft').toArray();

  for (i = 0; i &lt; elements.length; i++) {

    $(elements[i]).click();

    console.log(elements[i]);

  }"><pre class="notranslate"><code class="notranslate">await frame.evaluate(() =&gt; {

  const elements = $('.pivotTableCellWrap cell-interactive tablixAlignLeft').toArray();

  for (i = 0; i &lt; elements.length; i++) {

    $(elements[i]).click();

    console.log(elements[i]);

  }
</code></pre></div>
<p dir="auto">});</p>
<p dir="auto">The below is the closes I got, with the div nth child(1) but it returned the menu values at the top of the page and not from the visual before it gave me assert not defined.</p>
<p dir="auto">// Assert text content</p>
<p dir="auto">const corp = await page.textContent('div:nth-child(1) &gt; div:nth-child(4)');</p>
<p dir="auto">console.log(corp);</p>
<p dir="auto">assert(corp === 'Weimei Corp');  //assert is not defined</p>
<p dir="auto">const elementHandle = await frame.waitForSelector('#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(4)');</p>
<p dir="auto">await frame.click('text="Weimei Corp"');</p>
<p dir="auto">await frame.waitForFunction(() =&gt; {</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const searches = document.getElementsByClassName(&quot;.pivotTableCellWrap cell-interactive tablixAlignLeft&quot;);

console.log('found table');

return searches.length &gt; 1;"><pre class="notranslate"><code class="notranslate">const searches = document.getElementsByClassName(".pivotTableCellWrap cell-interactive tablixAlignLeft");

console.log('found table');

return searches.length &gt; 1;
</code></pre></div>
<p dir="auto">});</p>
<p dir="auto">I have been reading a lot. Your documentation indicates to not use xpath and css. I am not able to find a way to use div title to find the actual name and click on it.</p>
<p dir="auto">Avoid selectors tied to implementation<br>
xpath and css can be tied to the DOM structure or implementation. These selectors can break when the DOM structure changes.</p>
<p dir="auto"><a href="https://github.com/microsoft/playwright/blob/master/docs/selectors.md">https://github.com/microsoft/playwright/blob/master/docs/selectors.md</a><br>
<a href="https://stackoverflow.com/questions/48673906/collect-elements-by-class-name-and-then-click-each-one-puppeteer" rel="nofollow">https://stackoverflow.com/questions/48673906/collect-elements-by-class-name-and-then-click-each-one-puppeteer</a></p>
<p dir="auto">What I am trying to use this public visual to manipulate a click on "Weimei Corp" then I know I should be able to do the same on our internal reports.<br>
page.goto('<a href="https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893" rel="nofollow">https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893</a>')<br>
]);</p>
<p dir="auto">copy selector<br>
#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(4)</p>
<p dir="auto">copy jspath<br>
document.querySelector("#pvExplorationHost &gt; div &gt; div &gt; exploration &gt; div &gt; explore-canvas-modern &gt; div &gt; div.canvasFlexBox &gt; div &gt; div.displayArea.disableAnimations.fitToPage &gt; div.visualContainerHost &gt; visual-container-repeat &gt; visual-container-modern:nth-child(13) &gt; transform &gt; div &gt; div:nth-child(4) &gt; div &gt; visual-modern &gt; div &gt; div &gt; div.tableEx &gt; div.innerContainer &gt; div.bodyCells &gt; div &gt; div &gt; div:nth-child(1) &gt; div:nth-child(4)"</p>
<p dir="auto">copy element</p>
<div title="Weimei Corp" dir="auto">Weimei Corp</div>
<p dir="auto">Is there a way to reference the actual title versus using the long nth selector.</p>
<div title="Weimei Corp" dir="auto">Trying to click Weimei Corp<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/71278576/93516897-46affe80-f8f0-11ea-8421-3401ff6f994d.JPG"><img src="https://user-images.githubusercontent.com/71278576/93516897-46affe80-f8f0-11ea-8421-3401ff6f994d.JPG" alt="publicreport" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/71278576/93516900-47e12b80-f8f0-11ea-88a0-1ec225527743.JPG"><img src="https://user-images.githubusercontent.com/71278576/93516900-47e12b80-f8f0-11ea-88a0-1ec225527743.JPG" alt="dropdown" style="max-width: 100%;"></a><p dir="auto"></p></div>