Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's how Playwright works too


Doesn't work for logging into HN:

    from playwright.sync_api import sync_playwright
    playwright = sync_playwright().start()
    browser = playwright.chromium.launch()
    page = browser.new_page()
    page.goto('https://news.ycombinator.com/login?goto=news')
    page.get_by_label('username').fill('mherrmann')
    # playwright._impl._errors.TimeoutError: Locator.fill: Timeout 30000ms exceeded.
I suspect Playwright expects there to be a <label> for an <input> element.

It does work with Helium:

    from helium import *
    start_chrome('https://news.ycombinator.com/login?goto=news')
    write('mherrmann', into='username')
The two scripts are equivalent, except Helium's works and is half as long.


Depending on when you tried that, there is no such label "username" in view-source:https://news.ycombinator.com/login?goto=news

  <table border="0"><tr><td>username:</td><td><input type="text" name="acct" size="20" autocorrect="off" spellcheck="false" autocapitalize="off" autofocus="true"></td></tr><tr><td>password:</td><td><input type="password" name="pw" size="20"></td></tr></table><br>
as they only put text username not <label> and the input is named "acct" (without even the common decency to include autocomplete=username)

So if your script really did write that string into a what it thinks is 'username' then that's arguably one more thing to debug when its wizardry goes awry in some unknown way


Yes, there is no such <label>. There is only such <td>. And Playwright isn't smart enough to understand that that is still the label for the <input> element. Helium is smart enough.

So if your script really did write that string into a what it thinks is 'username' then that's arguably one more thing to debug when its wizardry goes awry in some unknown way

I tested my script. It writes into the correct field. The logic is not hard: "Find an element to the right of the given label." If there are multiple, then Helium uses the one that's closest to the last element it interacted with. That's just how a human would do it. It works surprisingly well. In many years of using Helium, I barely recall this causing problems once.

Try it before judging. You will be surprised by how well it works.


> And Playwright isn't smart enough to understand that that is still the label for the <input> element. Helium is smart enough.

I'm glad you like your project, and I'm sure there are others who will similarly enjoy that kind of magick. However, it's super disingenuous to write an example that asks a standards based API to find a non-existent element and then clutch pearls because it didn't find a non-existent element. page.get_by_label("I dunno, I didn't read, do what I am thinking").fill('lol') similarly would not work but that's not the awesome dunk you think it is


It's not disingenuous. The HN example was literally the first one I tried. It's what happens in the real world. The real world doesn't adhere to standards, much of the time.


Just like what you've done with Selenium, such a wrapper could be written for Playwright (I think that's what most developers end up doing anyways, just in a more domain-specific manner)


This project was started long before Playwright existed.

I's an OSS tool that had very good reason to be made the way it was at that time, and continues to be useful (in my opinion).


It is a useful tool, similar to others that accomplish the same task (WATIR and Capybara in Ruby, for example). My point was that the comparison of a wrapper to an underlying library is a bit apples to oranges, as a similar wrapper could be written for Playwright as well. I haven't looked at the code, but I assume Helium's API could be used to support Playwright (which itself was an evolution of Puppeteer).


I like what you're doing with Helium, and while you are technically correct that it's half as long - IMHO it's a bit disingenuous considering that in any meaningful web automation script, you'd only need to put in the initialization code a single time, e.g.:

    from playwright.sync_api import sync_playwright
    playwright = sync_playwright().start()
    browser = playwright.chromium.launch()
    page = browser.new_page()




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: