playwright-testing-library: Expect assertions can't be used due to returning ElementHandles instead of Locators
I was really excited to use this library/plugin, but I’m not sure I see the value when the standard Playwright expect
assertions aren’t supported for ElementHandles? I know this is a documented limitation, but I’m confused on the point of this module when expect assertions can’t be used.
Can you clarify the reason you’d want to use ElementHandles instead of Locators? It seems like Playwright discourages ElementHandles.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 46 (22 by maintainers)
Hey, @ScubaDaniel thanks for creating an issue. The reason this library uses
ElementHandle
s is thatLocator
s did not exist when it was originally created. We’ve been working on a new API that returnsLocator
s and leverages more @playwright/test features, there are just a few things I still need to sort out before we release it officially.I went ahead and released a beta version for you here. The readme hasn’t been updated there yet, though, so here’s a snippet from one of my commits with a basic usage example:
You can also reference the tests for more examples.
Let me know if you have any issues with that release, and feel free to provide any feedback in the PR → https://github.com/testing-library/playwright-testing-library/pull/403
Ah, one other thing is that the
configure
API is not yet implemented, but I have it mostly there, so let me know if you need that.@gajus just tried it out and this is what I’m seeing:
It looks good to me…? Let me know if I’m missing something.
Nice, thanks for the update and the snippet @gajus. I think there’s still value to this library in order to provide Testing Library parity in Playwright, but I’ll probably add something to the readme pointing out the role selector as an alternative.
I like to be pretty selective when considering
Proxy
, but this is a clever/convenient use case. Do you use TypeScript? Were you able to reliably augment/extend thePage
type with your custom methods?@ScubaDaniel heh, you had me worried for a second there as the
*ByRole
queries are the most important part of Testing Library imo — the issue you’re coming up against is that I don’t think thefindBy*
queries really make sense withLocator
’s and the underlying selector engine API that we use to implement theLocator
-based queries doesn’t support asynchronous calls.You can see my
TODO
here… 😬 https://github.com/testing-library/playwright-testing-library/blob/beta/test/fixture/locators.test.ts#L151I think there’s two action items here:
findBy*
doesn’t existIn looking back at your previous comment, it seems like you ended up looking for the
findBy*
methods after running into this problem trying to do it the Playwright way.I’ll try to take a look at this issue, as I was planning on supporting the
findBy*
cases using @playwright/test’s built-in asynchronous support. Hopefully, once this is resolved, you should have no need for thefindBy*
queries.@crazyvan25 I suspect your issue is actually related to this, I’ll let you know when I have a chance to dig into this stuff.
@sebinsua bleh, a dependency upgrade busted the second publish step, but I thought it went through on alpha. I manually published the Plawright Test package for
beta.3
, but I’ve now reverted the offending upgrade so it should be good going forward.@jrolfs Strangely the alpha seemed to be published under the package name
playwright-testing-library
only. Any ideas why? I’ll switch to the beta now anyway.I’m using it. It’s working great and I don’t have any additional feedback right now.
Also, I’m happy to help out with PRs and things if you’d like that.
In case y’all missed it, I published the
findBy*
/findAllBy*
stuff on v4.4.0-alpha.1 a few days ago — I finally sorted the Semantic Release stuff, so it’s also out on v4.4.0-beta.3. I’ll probably delete the alpha release to prevent confusion.@ScubaDaniel I know we co-opted your issue with all of this discussion, so I apologize for all the noise. If you’re still interested, you can try out the find queries with the aforementioned beta release.
@sebinsua let me know when you get a chance to try this stuff out. I’ll probably get the
screen
idea implemented as the last feature on the beta release channel. Unless you have additional feedback, I just have one last little thing I want to address before releasing this stuff officially on 4.x (I want to improve the error message for thefindBy
case that fails when an element is hidden. Right now the hard-coded100
ms timeout error will be confusing).After that, I’m planning on putting together a 5.0 release that consolidates both the @playwright/test and playwright use cases onto the new
Locator
stuff. All of the different APIs are pretty confusing right now, and as a bonus it will clean up the code considerably. I’ll probably throw together a quick codemod for preservingElementHandle
behavior vialocator.elementHandle()
to ease migration.Alright,
findBy*
queries are most of the way there in #488 if you wanna take a look. I stuck with Playwright’swaitFor
and got ourgetBy*
error idea working — I think using Playwright’s asynchronous utilities is ideal, if possible (as opposed to thewaitFor
from Testing Library).Shit, I forgot about this. This kinda makes me want to try another avenue I was considering… essentially implementing the
findBy*
the same way that @testing-library/dom does with thewaitFor
from @testing-library/dom. The other reason I was considering this was to surface the Testing Library error instead of the Playwrightlocator.waitFor()
timeout message (~I was also considering catching the timeout error and then running a finalgetBy*
to produce the error~ lol, oops I totally missed you mentioned this exact thing).Hrm, so you did get me thinking that perhaps the Playwright defaults would make the most sense here, but unfortunately, I don’t see any way of reading from the Playwright Test configuration in the documentation. Also, I do still want to keep supporting “vanilla” (sans @playwright/test) Playwright in some capacity going forward. I think I’ll probably stick with an independent
asyncUtilTimeout
value.Do you think implementing
waitForElementToBeRemoved
would sidestep this sufficiently? I’ll have to sit with this a bit, but let me know if you think there’s something you think we should change with thewithin()
implementation/behavior.Okay, so this is something I’ve wanted to address since I created this library. I’d be curious if you have an idea of what a better default implementation/output would be. I do think we can add support for this option, but I really think we also need a better default because the e2e use case just always produces so much output. I also want to figure out how to preserve the ANSI formatting in the Testing Library errors.
Thank you so much for all of this feedback!
The main project I use this library on is still on the
ElementHandle
version (and jest-playwright). We do have one other project at my company that’s using @playwright/test and the more modern version of this library, but it’s just smoke tests and hasn’t seen a lot of action in a bit.Note that this library is mostly redundant now that Playwright added ByRole selectors.
https://playwright.dev/docs/selectors#role-selector
If helpful, this is how we implemented it:
and then use it like any other selector
page.findByRole('button', 'Sign Up')
, etc.@jrolfs Sorry to bug you but how far away from an official release are you, and what version of the package contains all of these changes?
I need to write some E2E tests soon, and I’m trying to weigh up whether I produce a greater technical debt by using a beta package, or by continuing to build upon the custom selector engine I originally created – if I continue to use the latter, I’ll need to rewrite all of my tests once this is released.