Closed jrolfs closed 2 years ago
Love this!
Few considerations:
@gajus thanks for taking a look! Great points...
How does one create a new screen?, e.g. most of our tests use two browser contexts
Could you expand on this and/or provide a specific example? How exactly are you creating/using the additional contexts? I would hope that most of these use cases are solved for in @playwright/test so that simply configuring it to run with whatever contexts you need will ensure that all you need is the screen
fixture that wraps the page
that Playwright provides and @playwright/test manages executing the tests in different contexts.
@sebinsua I guess you had a similar use case that prompted you to suggest we expose queriesFor
. I'd be curious to hear more about your case as well.
Somewhat related: I am trying to figure out the Locator
API I want to use for the "vanilla" playwright use case where fixtures aren't an option. I was thinking of something like const screen = getScreenForPage(page)
, but it would need to set up the selector engine, read a global configuration, and inject the Testing Library script into the page
instance "on demand" since we can't rely on @playwright/test fixtures in that case. Maybe something like this makes sense:
const screen = attach(page)
— sets up selector engine, wires up global configuration, injects script (for vanilla playwright
) and then returns Page
instance wrapped with Screen
const screen = getScreenForPage(page, { /* optional configuration */ })
— "lower level" utility that simply wraps a Page
instance with Screen
(the configuration bit is necessary because there's no good way of wiring up the test.use
configuration to this function since it's not a fixture. I see this bit as being a little confusing but we can just make sure to document it as such.)Does chaining work? This was one of the limitations we faced with our Proxy implementation https://github.com/microsoft/playwright/issues/16785
So I had been considering just sticking with within(locator: Locator)
here for consistency with Testing Library, but @sebinsua also asked about this and I don't want to adhere to the Testing Library API solely for the sake of consistency. I could see chaining being quite powerful, and probably a bit more of an idiomatic implementation since we're working with Locator
s. I can also see within()
/chaining being much more common in e2e tests when compared to unit tests. I think I'm gonna try implementing something that would even work with the asynchronous find*
queries.
// Synchronous
const locator = screen.getByRole('form').within().getByRole('textbox');
// Equivalent
const formLocator = screen.getByRole('form');
const locator = within(formLocator).getByRole('textbox');
// Asynchronous (waits for a delayed `<form />` and then queries within it if found)
const locator = await screen.findByRole('form').within().getByRole('textbox');
// Equivalent
const formLocator = await screen.findByRole('form');
const locator = within(formLocator).getByRole('textbox');
I'll have to prove out some assumptions I've made regarding some cleverness that'd be necessary to handle the async stuff. I'll try to get something hacked together soon, but let me know if you have a different angle in mind.
@gajus take a look at #501 for my take on chaining so far.
Additional thought regarding:
How does one create a new screen?, e.g. most of our tests use two browser contexts
We could continue to expose the within()
fixture as an alternative to chaining and if you pass it a Page
instance, it would return a Screen
instance.
Looks good. I would def expose within()
though, since it will be needed for anyone who is testing more than 1 page.
CC @alyaothman14 who currently owns Playwright migration on our team, in case she has input here.
Would you be able to use the within()
provided as a @playwright/test fixture @gajus / @alyaothman14? Just curious because that one is currently wired up to the test.use()
configuration whereas the imported function needs to be configured independently.
Either way, I'm going to add the Screen
functionality to within()
in this PR and get it released on beta for y'all.
:tada: This PR is included in version 4.4.0-beta.6 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
@gajus / @alyaothman14 released on beta 🥳
Thanks to @gajus for the inspiration here. This adds a
screen
fixture that combines Playwrightspage
API with the document-scoped Testing Library queries (queries
). This will likely replacequeries
altogether in the official release of this stuff.Example