[HN Gopher] Web Automation: Don't Use Selenium, Use Playwright
       ___________________________________________________________________
        
       Web Automation: Don't Use Selenium, Use Playwright
        
       Author : rekahrv
       Score  : 90 points
       Date   : 2022-11-09 21:01 UTC (1 hours ago)
        
 (HTM) web link (new.pythonforengineers.com)
 (TXT) w3m dump (new.pythonforengineers.com)
        
       | plugin-baby wrote:
       | I've tried writing e2e tests for web apps using browser drivers
       | on-and-off for the last decade, and it feels like with playwright
       | that the tech has finally matured enough to make the tests
       | reliable enough to be worth the effort of maintaining them.
        
         | sh4rks wrote:
         | What does Playwright do that Selenium can't do?
        
           | cebert wrote:
           | Playwright can run tests in multiple windows as well as tests
           | that cross multiple domain origins. My team builds a
           | collaborative app where we wanted to cover scenarios where
           | two different users collaborated on the same page. This was
           | easy to implement in Playwright, in Cypress it is not
           | possible.
           | 
           | Also Playwright is a general browser automation tool and can
           | be used for more things than just testing. For example,
           | scraping website data or generating preview thumbnails for
           | URLs.
        
           | aziaziazi wrote:
           | The author says the killer feature is:
           | 
           | > Playwright "records" your steps and even gives you a
           | running Python script you can just directly use (or extract
           | parts from). I'm serious about the running part- I can
           | literally record a few steps and I will have a script I can
           | then run with zero changes.
           | 
           | Does Selenium have that ?
        
           | ncrmro wrote:
           | Run inside a container with near zero effort for CI pipelines
        
           | voxic11 wrote:
           | The main difference is that Playwright uses custom headless
           | builds of "browser projects" (like chromium) rather than
           | attempting to automate a normal consumer build of the browser
           | via the webdriver api. The webdriver api is kind of slow,
           | browsers don't always implement it well, and it doesn't have
           | a good mechanism for the browser to push events back to the
           | test application which ends up requiring selenium to do a lot
           | of polling for changes so it can miss events that happen
           | quickly.
        
             | geoelectric wrote:
             | Does it have a mode where it _can_ drive a real browser?
             | Most real-world UI test matrixes for web apps want the
             | tests run on their real targets for any final acceptance.
             | "Fake" headless browsers tend to be more useful for first-
             | tier CI and just keeping tests warm.
             | 
             | If it can only drive its internal browser engine, that'd
             | possibly be a big argument against it for any test strategy
             | I was architecting. I'd want the tests to be portable and
             | usable cross-browser for acceptance--particularly UI-driven
             | E2E tests, since that's really the _only_ time they are
             | critical.
        
             | ethbr0 wrote:
             | Events are the bane of automation existence.
             | 
             | Back in Windows-heavyweight app land, it made way more
             | sense to interpose a low overhead shim to intercept and
             | copy events.
             | 
             | I can't imagine the pain you'd encounter trying to paper
             | over the other way around.
        
       | MetaWhirledPeas wrote:
       | > So much so, I started looking at Javascript testing frameworks
       | like Chai, Mocha, Cypress etc. The problem I found is that they
       | require a completely different setup, and aren't easy to get
       | started for someone from a Python background.
       | 
       | A shame to see Cypress lumped in and dismissed like that. It
       | really is a fantastic way to test.
       | 
       | > The killer feature of Playwright is: You can automatically
       | generate tests by opening a web browser and manually running
       | through the steps you want. It saves the hassle I faced with
       | Selenium, where you were opening developer tools and finding the
       | Xpath or similar. Yuck
       | 
       | This is absolutely _not_ the primary hassle with testing.
       | Recording steps can help kick start your testing, sure. But very
       | quickly you start to realize that it 's only saving you from the
       | easiest work at best, and is creating flaky tests at worst.
        
         | [deleted]
        
         | TheFattestNinja wrote:
         | 99% sure record tab is available in selenium as well
        
           | masklinn wrote:
           | "Selenium IDE" is the recording tool:
           | https://www.selenium.dev/selenium-ide/
        
           | eddsh1994 wrote:
           | Yeah that was their main product for QA. I'm pretty sure most
           | outsourced companies just use that and add waits to make
           | things green more often lol
        
       | simonw wrote:
       | I just spent half an hour wrestling with Selenium for Python and
       | that API has NOT aged well.                   content =
       | driver.find_element(By.CSS_SELECTOR, "p.content")
       | 
       | In Playwright Python:                   content =
       | page.locator("p.content")
       | 
       | Playwright is just nicer to use. Selenium feels very Java-ish.
        
       | kc10 wrote:
       | > I found weird issues (when using the recorder) where I couldn't
       | scroll down to the bottom of the screen in Playwright's Chromium,
       | but could in a normal Chrome, forcing me to use other tricks to
       | click the button.
       | 
       | You may consider trying this extension -
       | https://chrome.google.com/webstore/detail/devraven-recorder/....
       | This extension can record the tests using your Chrome browser
       | instead of launching a separate Playwright chromium browser. Full
       | disclosure: I am the developer of this extension.
        
       | 999900000999 wrote:
       | Playwright is good, but stop thinking auto generated code is
       | worthwhile.
       | 
       | Eventually you'll have to write your own scripts. I will admit
       | Playwright can spit out code that will at least serve as a
       | starting point.
        
         | cebert wrote:
         | If you use automation attributes on your components it can work
         | quite well.
        
       | irsagent wrote:
       | It must be a game changer as Selenium is mentioned, but never
       | linked in the article.
        
       | starik36 wrote:
       | Unfortunately, the .NET library doesn't support ARM processors.
       | Thus, I can't use it on the Raspberry Pi. But PuppeteerSharp
       | works great on the Pi.
        
       | lucasfcosta wrote:
       | I've used playwright for a while, especially on my day job.
       | 
       | It's a fantastic and versatile tool. I couldn't agree more.
        
       | geoelectric wrote:
       | You're going to get a lot of responses that say record-replay
       | testing doesn't scale, is unmaintainable, etc. They're totally
       | right.
       | 
       | But the thing is, early on when your app is in flux, neither does
       | writing Selenium code. There's a pretty big truism in UI
       | automation that writing UI tests before a UI freeze is a recipe
       | for a shit-ton of pain. Coding to ids or xpaths only gets you yay
       | far if the UI flow itself fundamentally changes.
       | 
       | But re-recording might be easy.
       | 
       | Don't use stuff like this for long-standing tests. Unless you
       | architect your app just right so that IDs are always stable, and
       | you never change the interface, it'll break and break in ways
       | that you can only fix by a complete re-record. Plus the tests
       | tend to be extremely timing-fragile because recording uses delays
       | instead of synchronization points, so they just won't work in CI.
       | 
       | But _do_ use stuff like this at your desk during bring-up, when
       | the cost of a re-record is lower than the cost of a test rewrite
       | and it 's ok to re-run the thing if the first try craps out due
       | to a timing glitch.
       | 
       | And from there, keep an open mind.
       | 
       | I went to a GTAC (Google testing conference) where a presentation
       | made a very good argument--with numbers and everything--that for
       | smaller projects with simple and more or less static UIs, and
       | where the tests were all fundamentally scripted, there was almost
       | no advantage to coding the tests later. Record-replay was the
       | best way to go.
       | 
       | But I definitely don't think a system like PlayWright fully
       | replaces remote stubs like WebDriver and coding tests in the
       | languages that can talk to it.
       | 
       | At some point you hit the issue that the login screen changed and
       | now every single test is invalid. It's awfully nice if you used
       | Page Object Model and you have a single-point-of-truth to fix it.
       | 
       | More to the point, test automation can do more than just execute
       | a script repeatably. Randomized monkey testing is something you
       | can really only do in code, ditto scenarios that need to talk to
       | testing interfaces exposed from the app itself.
       | 
       | Glad you found a tool that resonates with you!
        
         | pydry wrote:
         | Record-replay doesnt even work when running the same scenario 2
         | minutes later half the time - never mind in 2 months' time.
         | 
         | I tend to find in most apps that unless you directly change the
         | front end templates to give elements you interact with better
         | identifiers and then deliberately use those identifiers your
         | browser tests will always end up an unreliable sucky mess.
        
           | geoelectric wrote:
           | Agreed, giving it at least stable identifiers to play with
           | makes a huge difference. With some front end generators, that
           | may not be trivial, though I'd think Selenium being a thing
           | (POM does rely heavily on stable unique identifiers, since
           | "nth element past m" xpath queries are way more fragile) has
           | probably made it more of a standard ask.
           | 
           | Dynamically-created UIs are usually the hardest thing to deal
           | with--if they get a different ID every time, record-replay is
           | out the door, and even Selenium is a lot harder.
           | 
           | But personally, with a lot of automation architecture
           | experience, I think you're exaggerating a little re: doesn't
           | work 2 minutes later half the time. But it also depends on
           | whether your app is driving some invisible external resource
           | that makes the timing highly variable, etc. Even then you can
           | usually "harden" the recording by putting in worst-case
           | delays. It's just that then your test takes so long to run
           | you can't CI it either.
           | 
           | It's really situational. What I'm arguing against more than
           | anything is the knee-jerk reaction that it's _never_
           | appropriate. It 's just never _enough_ usually. The fact that
           | we tend to skip over the option entirely in testing is
           | probably a blind spot and a mistake. Devs dabbling in testing
           | as a side task definitely shouldn 't ignore the option.
        
       | ffgh wrote:
       | I find that Hero[https://ulixee.org/docs/hero] has been a good
       | replacement for my selenium needs
        
       | lyu07282 wrote:
       | My journey has been Selenium, then Cypress, then Playwright.
       | 
       | This was the first time I was happy writing ui tests, Playwright
       | is great!
       | 
       | (Though I don't use the recording tool at all this article
       | focuses on I rather write the tests manually)
        
         | baal80spam wrote:
         | > Though I don't use the recording tool at all this article
         | focuses on I rather write the tests manually
         | 
         | That's because automatic code generators rarely work (anything
         | more dynamically generated and it's a no-go).
        
           | GenerocUsername wrote:
           | I manually do it, then replace parameters where needed
        
         | dvngnt_ wrote:
         | i miss the cypress test runner
        
           | MetaWhirledPeas wrote:
           | Yes, Cypress has many killer features, including:
           | 
           | - The Test Runner lets you retrace your actions with a visual
           | UI and interact with the page as you rewind, with access to
           | Dev Tools the whole time. It also has an excellent tool for
           | targeting elements. (Although you'll eventually lean more on
           | Dev Tools once you're fluent with CSS selectors.)
           | 
           | - There's very little boilerplate for anything. Several
           | useful libraries are packed in and available globally.
           | 
           | - You can easily spy on and interact with fetch and XHR on
           | the page
           | 
           | - You can easily execute Node stuff
           | 
           | - They have a great Dashboard (their only pay feature)
        
           | lyu07282 wrote:
           | The thing about cypress that annoyed me the most was how it
           | wasn't just using async/await syntax, generating more complex
           | tests dynamically is super hard. Just try to write a test
           | that follows links on a site dynamically, I couldn't figure
           | it out.
        
             | MetaWhirledPeas wrote:
             | Like this maybe?
             | https://www.cypress.io/blog/2020/12/10/testing-the-anchor-
             | li...
             | 
             | If that's not it keep looking. If there's a thing you want
             | to do, odds are Gleb has a video or blog post about it.
        
               | lyu07282 wrote:
               | The thing they do with posts.json, except dynamically
               | from links discovered on a page. I did look, I don't
               | think its possible.
               | 
               | Anyway its subjective, I don't like Cypress.
        
               | stnmtn wrote:
               | There's no way to search the current page for all
               | elements of an `<a>` type, then through that list search
               | for the one you want and call click on it?
               | 
               | I figure there must be a way to do that, but it's very
               | possible I'm misunderstanding what you're trying to
               | solve!
        
             | btown wrote:
             | Cypress requires developers to have a mental model of
             | "calling a Cypress function actually adds an action to the
             | back of a queue and immediately returns control flow
             | without waiting for that action to run." And this is fine
             | if you can express your waits and conditions declaratively
             | - you give Cypress a plan, it decodes the plan from your
             | Cypress code in milliseconds, and then will take as long as
             | it needs to execute that plan.
             | 
             | And Cypress gives a great API surface where _almost_
             | everything can be done with just this declarative API, and
             | it enables them to show the full plan in a UI even while it
             | 's executing.
             | 
             | But if you actually need custom control flow, with code you
             | control... you need to "pause" your action-enqueueing to
             | let Cypress catch up. Which means you're going to be
             | nesting callbacks, or sprinkling awaits in all the places
             | that _aren 't_ logically awaiting, because you need an
             | explicit yield point out of your JS block. Our team finds
             | this rare enough that it's acceptable. But... yeah, it's
             | far from a perfect solution.
        
       ___________________________________________________________________
       (page generated 2022-11-09 23:00 UTC)