Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proof of concept idea for "By" #10801

Closed
wants to merge 2 commits into from
Closed

Conversation

brad-decker
Copy link
Contributor

Playwright supports chaining selectors together in string format. Example:

page.click('css=nav >> text=Login');

Java versions of selenium-webdriver support chaining By methods using ByChained, but that doesn't appear to have a corollary in js.

This proposal creates a new By class that composes selectors together and turns them into an xpath selector at the end (for selenium). Once every usage of selenium's By() is replaced with our By() we can remove the call to toSelector() at the end and have that be the job of our Driver's various element methods.

Once we're ready for playwright we can change how the chaining occurs because we don't need xpaths, we can remove the dependency added in this PR and combine selectors using string concatenation with >>.

@@ -28,6 +28,7 @@
"test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh",
"test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js",
"test:e2e:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-all.sh",
"test:e2e:firefox:one": "SELENIUM_BROWSER=firefox test/e2e/run-one.sh",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore this lol, for local testing :P

@rekmarks
Copy link
Member

rekmarks commented Apr 1, 2021

If we're migrating to Playwright (are we?), how do these changes track with their API?

As for the By abstraction, it is definitively nicer than typing out xpath strings, lol.

@brad-decker
Copy link
Contributor Author

If we're migrating to Playwright (are we?), how do these changes track with their API?

I laid out the plan for making this a thing we can use with Playwright in the description. Essentially we just change the internals of By to concatenate strings differently and it won't use xpaths at all

@brad-decker
Copy link
Contributor Author

now to figure out why this works locally and not in test environment 🤦🏻‍♂️

}

static css(selector) {
return new By(parse(selector));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how this works on Playwright, but on Selenium I've been trying to avoid using xpath because I've heard it was fairly slow in comparison to ID or CSS selectors. Normalizing to xpath might make things slower? Not sure 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

til

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a viable idea!

The one alternative I've considered is passing in a plain object, where the key represents the different attributes you're selecting by, e.g. driver.clickElement({ tag: 'button', text: 'Confirm' }).

Or maybe something simpler to implement, where only 1 key is allowed and it represents the selector type, like driver.clickElement({ xpath: '...' }).

@brad-decker
Copy link
Contributor Author

so remove the usage of By altogether in favor of making the selector functions in Driver more robust? @Gudahtt

@tmashuang
Copy link
Contributor

tmashuang commented Apr 1, 2021

I thought the motivation to switch to Playwright was to not have to create custom wrappers for everything?

The one alternative I've considered is passing in a plain object, where the key represents the different attributes you're selecting by, e.g. driver.clickElement({ tag: 'button', text: 'Confirm' }).

This can be done in Playwright.

await page.click('article:has-text("Playwright")');

@brad-decker
Copy link
Contributor Author

would that be different than tag=article >> text=Playwright @tmashuang ? The reason I ask is because the latter is easier to reason about in terms of combining terms

@rekmarks
Copy link
Member

rekmarks commented Apr 1, 2021

I laid out the plan for making this a thing we can use with Playwright in the description.

Don't mind me 🤦

@tmashuang
Copy link
Contributor

The chaining could be more robust to include more selectors, and the combination could be limited to a certain number.

@brad-decker
Copy link
Contributor Author

@tmashuang -- the task i'm working on is extracting the selenium portions of the tests into our own wrapper... which was meant to ease the transition into playwright. Presumably the next piece would be switching out our abstraction from using selenium to using playwright. how about this:

  clickElement(selector: string | SelectorObject) {
    if (typeof selector === 'string') {
      return seleniumImplementation(By.css(selector));
      // playwright will be something like this.page.click(selector);
    } else {
      // do other magic here.
    }
  }

@brad-decker
Copy link
Contributor Author

@tmashuang @Gudahtt take a look at the latest commit which includes a change that would allow us to pass in fully powered playwright selectors as strings, and in the interim pass in css selectors as strings for selenium, and take advantage of the aforementioned xpath/ text/tag combos. I only did half the from file, because the implementation also accepts By locators, so I could merge just the webdriver portion in and break apart the other transformations into separate PRs.

if (typeof locator === 'string') {
return By.css(locator);
} else if (locator.value) {
return locator;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was this branch for?

Copy link
Contributor Author

@brad-decker brad-decker Apr 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Selenium locators have a .value prop,

@Gudahtt
Copy link
Member

Gudahtt commented Apr 1, 2021

I like this idea - it seems very compatible with both selenium and playwright selector APIs.

@brad-decker
Copy link
Contributor Author

Thanks @Gudahtt! this has been superseded by #10802

@brad-decker brad-decker closed this Apr 1, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Apr 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants