Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question]Can Playwright be used to manipulate a Power BI visual? #3915

Closed
wadezone opened this issue Sep 17, 2020 · 4 comments
Closed

[Question]Can Playwright be used to manipulate a Power BI visual? #3915

wadezone opened this issue Sep 17, 2020 · 4 comments

Comments

@wadezone
Copy link

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
publicreport
dropdown

@arjunattam
Copy link
Contributor

arjunattam commented Sep 17, 2020

Thanks for writing in, @wadezone. I'm not exactly sure if I understand the issue but I was able to use the website that you've shared to play with the app a bit and write a starter script using with Playwright.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto('https://community.powerbi.com/t5/Data-Stories-Gallery/Customer-Analysis-Dashboard/td-p/630893#');
  const frame = page.frame({ url: 'https://app.powerbi.com/view**' });
  await frame.click('text="Weimei Corp"');
  await frame.click('text="Weimei Corp"', {button: 'right'});
  await frame.click('text="Copy"');
  await frame.click('text="Copy value"');
  
  await browser.close();
})();

I was able to click on the selector with text="Weimei Corp and do some actions on the right-click context menu. Are you thinking of building something like this? If you have a specific question, please feel free to re-open the issue.

@wadezone
Copy link
Author

Thanks for taking a look at that. I did do a playwright cli on that sight and the difference between that report and ours is this line. We don't have a view reference for our frame. This might have been required for them to make it public.

const frame = page.frame({ url: 'https://app.powerbi.com/view**' });

My playwright is only returning the following when I click on the name which isn't working.
// 0× click
await page1.click('//iframe');

// Click text="THERESA WADE"
await page1.click('text="THERESA WADE"');

When I do this below I get the iframe name but unable to figure out how to reference the items in the rows
//locate the iframe name visual sandbox
const frame = page.frames().find(frame => frame.name() === 'visual-sandbox');
console.log(frame.name());

@wadezone
Copy link
Author

@arjun27 I couldn't figure out how to re-open this issue. First time utilizing a forum/issue, sorry very new to this. I did find through playwright cli recording on the public site that I too was able to get the click to work and found it was utilizing the view. Our reports do not have this. I checked with my development team management and indicated why. The "public" reports are deployed using the tokenization feature of Power BI Service. It is insecure way to deploy reports, and this is turned off for our reports. The Publish to Web feature in the service uses tokenization to try to obfuscate the report being published. It doesn't really work because of google. When google indexes the web, even through the URL is obfuscated, the report is searchable.

I have tried so many things. What is the proper object to use to get it to click and to even "get" the values on the row?

@arjunattam
Copy link
Contributor

arjunattam commented Sep 18, 2020

What is the proper object to use to get it to click and to even "get" the values on the row?

page.click or frame.click can be used to click elements, depending on whether you click in the main frame or a specific iframe. Please see click docs for more info.

For getting info, you can refer to these common patterns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants