-
Notifications
You must be signed in to change notification settings - Fork 41
Conversation
|
||
// WHEN: connected a Wallet | ||
// Click text=/.*Connect Wallet.*/ | ||
await page.click('text=/.*Connect Wallet.*/') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look like a specific (HTML) selector but rather (regex?) looking for a specific text string. Unless I misunderstand this piece, is it better to scope down to the selectors so that their presence is validated too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to do testing from user perspective
page.click('text=/.*Connect Wallet.*/')
represents
- User comes to a page
- User sees text, not a selector, not even necessarily link or button
- User doesn't care, text looks clickable
- User clicks
That's what playwright docs recommend and what some other libraries (like react-testing-lib) advocate for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Selector presence is for unit (not even integration) testing with libs that like comparing snapshots, like Enzyme
Look up Enzyme vs react-testing-library approaches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that open up possible collusions/complexity around identical naming conventions for text/labels? Or do you see that as an advantage in terms of enforcing a better user experience for the user? I like the thinking here otherwise, but curious on your thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although after reading the docs, I wonder if using an actual user-facing attribute like 'aria-label' or 'title' (etc.) would be better. It would thick both the 'selector' and 'user facing attribute/text' boxes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it does, you are completely right. Trade offs are trade offs
That's why I use header >> text=Web3
in another click, for specificity
You can even argue, as you are saying, for better user xp. For example we have Connect Wallet
both in header and in TradeOrders component (when disconnected). But they do the same, so we shouldn't care which user clicks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the test will only click the first found item? E.g. I guess we want to be sure to test all possible instance for working properly as expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
We want to be sure of the whole user flow
So to properly test we would need to do txs
And not rely on rinkeby random address
So setup ganache and deploy contracts locally and who knows what else
So yes,and no 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
// THEN: wallet connected & address available | ||
// XPATH: closest ancestor with 0x* text of element with text "Copy address to clipboard" | ||
const textWithAddress = await page.textContent( | ||
'//*[text()="Copy address to clipboard"]//ancestor::*[starts-with(., "0x")][1]', | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@biocom
This is a good example of playwright approach.
As there aren't better ways to distinguish where the address is, instead of <wallet popup class which is pseudo-random with hash 'cause generated by styled-comps> > text that looks like address
I opted for Copy address to clipboard button > closest parent with address
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is quite thorough, which is good. As opposed to testing for selectors.
What if there a multiple of these components doing the same thing for some reason? page.Textcontent() only returns the first found item? E.g. would be good to test the validity of any other similar/identical item on page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very well may be
Like here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
playwright/utils/test_setup.ts
Outdated
|
||
beforeAll(async () => { | ||
// launch chrome,headless by default | ||
browser = await chromium.launch({ slowMo }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we hardcoding the tests to chromium?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have to hardcode something
can of course do BROWSER=chromium|firefox|webkit
and later pick it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also can think about an optional executablePath
argument, to use Chromium but use your local installed Chrome browser. Should in theory be the same I suppose (Chromium <-> Chrome) but there can be nuances in practice when testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, can't count on Chrome extensions not screwing everything up
Because if you just use local Chrome, and have MMask installed, it will conflict with window.ethereum
injected by playwright
And if you use local Chrome with --sandbox
or whatever no-extension flag, then it's almost the same as Chromium
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my thinking is:
- Even having 'expected' extensions like MM, might simulate/catch some side effects/bugs as opposed to run it in a clean env. like Chromium.
- Same for running Chromium vs Chrome, like you say they are almost the same but I'd regard it as a more realistic test if you know what I mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this is interesting indeed. Can do
BROWSER=chromium EXECUTABLE_PATH=$(which google-chrome) yarn test:playwright
@@ -31,7 +31,8 @@ | |||
"cypress": "cypress open", | |||
"cypress:run": "cypress run", | |||
"playwright": "jest --roots playwright --no-cache", | |||
"playwright:debug": "PWDEBUG=1 jest --roots playwright", | |||
"playwright:rebuild": "ts-node ./playwright/utils/build_injects.ts", | |||
"playwright:debug": "PWDEBUG=1 jest --roots playwright --runInBand", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call creating this script
This is strange. How did you run? what command?
|
Added serve -s -l 8080 dist
BROWSER=chromium EXECUTABLE_PATH=$(which google-chrome) yarn playwright #or brave browser
BROWSER=firefox yarn playwright
BROWSER=webkit yarn playwright
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good job.
The injection was a bit hacky, I mean. programmatically using webpack to compile the wallet, ...
I haven't gone over all the doc, so not sure if there's simpler way. I would think so, but just glad u found a solution.
|
||
// WHEN: connected a Wallet | ||
// Click text=/.*Connect Wallet.*/ | ||
await page.click('text=/.*Connect Wallet.*/') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you use a "pattern", is not needed right? (since text selector already searches for partial text matching)
Also, I think it's more readable the short-form
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've try it out here, feel free to merge if u agree #1631
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern was made by playwright itself during playwright:record
, I just didn't think twice to change it
playwright/utils/test_setup.ts
Outdated
jest.setTimeout(30000) | ||
if (isDebug) { | ||
// slow down playright actions | ||
slowMo = 2000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a const on top, and explain that artificially delay the test to visually see what is going on
Simplify text selectors
window.ethereum
)To see it perform and to test/debug please run
Actually please just run that so we can check it works on different machines