Issue 1:
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 (& "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?

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.

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?

For the examples, I figured it should be from frame and not page but I would try both.

Copy Element

Weimei Corp

Copy Selector

#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)

Copy JS Path

document.querySelector("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)")

Copy XPath

//*[@id="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]

Here is the code using that public visual and example codes I have tried to just click the "Weimei Corp"

const playwright = require("playwright");

(async function(){

const browser = await playwright.chromium.launch({ headless: false , slowMo: 100 }); // Non-headless mode to feel comfy

const context = await browser.newContext(); // So much to say, but another time

const page = await context.newPage(); // Create a new Page instance which handles most of your needs

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

debugger;

console.log('start');

console.log('Report is displayed');

await page.frames().find((frame) => {

console.log(frame,frame.name());

return frame.name() === 'visual-sandbox'

});

console.log('Got visual-sandbox');

//locate the iframe name visual sandbox

const frame = page.frames().find(frame => frame.name() === 'visual-sandbox');

console.log(frame.name());

console.log('Got visual-sandbox');
const title= await frame.title();
await console.log('title is:'+title);

await frame.waitForTimeout(10000);

// below doesn't work

await page.click('text="Weimei Corp"');

await frame.click('text="Weimei Corp"');

//Error: Evaluation failed: TypeError: Cannot read property 'click' of null

const corp = await page.evaluate(() => document.querySelector("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)").click());

console.log('got Corp click ');

// Error: Evaluation failed: TypeError: Cannot read property 'innerText' of null

const fullText = await frame.evaluate(el => el.innerText, await page.$("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)"))

//console.log(fullText)

//TypeError: Cannot read property 'inntertext' of null

//const hrefElement = await page.$('#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)');

console.log(hrefElement.innerText.name);

await hrefElement.click();

//(node:10080) UnhandledPromiseRejectionWarning: Error: Error: failed to find element matching selector "#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)"

// at Frame._$evalExpression

const hrefElement = await frame.$eval('#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)', el => el.value);

console.log(hrefElement);

await hrefElement.click();

//(node:21332) UnhandledPromiseRejectionWarning: Error: page.waitForFunction: Evaluation failed: TypeError: Cannot read property 'length' of null

await frame.waitForFunction(() => {

const searches = document.querySelector(".pivotTableCellWrap cell-interactive tablixAlignLeft");

console.log('found table');

return searches.length > 1;

});

await frame.waitForTimeout(10000);

await frame.waitForFunction(() => {

const searches = document.getElementsByClassName(".pivotTableCellWrap cell-interactive tablixAlignLeft");

console.log('found table');

return searches.length > 1;

});

await frame.waitForTimeout(10000);

//assert is not defined

//const datatext = await page.$$eval('#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(5)',

elements => elements.map(el => el.textContent.trim().split('\n')[0]))

assert(datatext.length > 0)

//Error: Evaluation failed: TypeError: Cannot read property 'getAttribute' of undefined

const myElem = await frame.evaluate(el => el.getAttribute('Weimei Corp'));

console.log(myElem)

const element = await page.$('#pvExplorationHost');

await page.waitForFunction(() => {
const searches = document.querySelectorAll('div.tableEx');
console.log('found table');
return searches.length > 1;
});

await browser.close(); // Close the browser

})();

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.

"COPY ELEMENT"

THERESA Z WADE

"COPY SELECTOR"

#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(3) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1)

#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(3) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div

"Copy JS Path"

document.querySelector("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(3) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div")

"Copy XPath"

//*[@id="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

Issue 2:
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?

Currently unable to reference elements in a visual. For a single cell the select value is very long.

//doing this I get Error: Evaluation failed: TypeError: Cannot read property 'click' of null

const corp = await frame.evaluate(() => document.querySelector("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(4)").click());

I tried to do a for each but not sure how to verify the "elements" array was populated with data with the

TypeError: Cannot read property 'click' of undefined

await frame.evaluate(() => {

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

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

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

console.log(elements[i]);

}

});

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.

// Assert text content

const corp = await page.textContent('div:nth-child(1) > div:nth-child(4)');

console.log(corp);

assert(corp === 'Weimei Corp'); //assert is not defined

const elementHandle = await frame.waitForSelector('#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(4)');

await frame.click('text="Weimei Corp"');

await frame.waitForFunction(() => {

const searches = document.getElementsByClassName(".pivotTableCellWrap cell-interactive tablixAlignLeft");

console.log('found table');

return searches.length > 1;

});

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.

Avoid selectors tied to implementation

xpath and css can be tied to the DOM structure or implementation. These selectors can break when the DOM structure changes.

https://github.com/microsoft/playwright/blob/master/docs/selectors.md

https://stackoverflow.com/questions/48673906/collect-elements-by-class-name-and-then-click-each-one-puppeteer

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.

page.goto('https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893')

]);

copy selector

#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(4)

copy jspath

document.querySelector("#pvExplorationHost > div > div > exploration > div > explore-canvas-modern > div > div.canvasFlexBox > div > div.displayArea.disableAnimations.fitToPage > div.visualContainerHost > visual-container-repeat > visual-container-modern:nth-child(13) > transform > div > div:nth-child(4) > div > visual-modern > div > div > div.tableEx > div.innerContainer > div.bodyCells > div > div > div:nth-child(1) > div:nth-child(4)"

copy element

Weimei Corp

Is there a way to reference the actual title versus using the long nth selector.

Trying to click Weimei Corp