I've tried to find a solution online on how to work with playwright and vaadin code but no chance. Playwright is installed in VS Code, is up and running, I have my test explorer installed and node.js. etc...
The FE that I need to automate(and I'm doing this in .ts) has vaadin code. But calling the selectors with xpath or by simple id locator doesn't work. Anybody an idea on how to do so please? This is an example for login:
import { test as setup } from '@playwright/test';
import path from 'path';
const authFile = path.join(__dirname, '../playwright/auth.setup.ts')
setup('authenticate', async ({ page }) => {
await page.goto('https://aservice.somewhere/mypage-ui/login');
await page.locator("xpath=//*[id='vaadinLoginUsername']").fill('_famname');
await page.locator("xpath=//*[id='vaadinLoginPassword']").fill('_passw');
await page.locator("xpath=//button[@part='vaadin-login-submit']").click();
await page.waitForURL('https://aservice.somewhere/mypage-ui/home');
await page.context().storageState({ path: authFile});
})
Even if I add a click() function to it, playwright debugger freezes on the first locator.
Thanks in advance!
1 Answer 1
I wrote a blog post about that a while ago: https://martinelli.ch/ui-testing-with-vaadin-and-playwright/
This is how to use the login form
page.locator("vaadin-text-field[name='username'] > input").fill(username);
page.locator("vaadin-password-field[name='password'] > input").fill(password);
page.locator("vaadin-button").click();
It's Java code, but it should also work with TypeScript if you add await in front of each line above.
Btw., why do you use TypeScript with Vaadin? Because if you use Vaadin, I assume you are a Java developer, and Playwright works well with Java, and you can run it with JUnit.
8 Comments
page. methods aren't discouraged. Playwright's Best Practices page uses plenty of page. in suggested examples. What's discouraged is relying on things that can change, such as CSS class names. A web component's Parts (such as the input part of a <vaadin-text-field> element) are a part of its public API, so it's not going to change without a major version change of the component library and it'll need a really good reason with that.page. methods, like page.click() and page.fill() which you used originally. Those are discouraged because they don't auto-wait and aren't reusable. "Can change" is not the main reason CSS selectors are discouraged, although that's part of it, if you rely on arbitrary nested structures; the concern is that they're not user-visible and have zero semantic relevance to a user.page.locator("vaadin-button").click(); is very likely to throw a strict mode violation. Most pages have more than one button in them, and this locator has no way to disambiguate. Normally you'd use page.getByRole("button", {name: "foo"}), which is totally framework agnostic. I'm not sure which framework of the week "vaadin" is but I don't want to hardcode it into all of my tests, especially if it doesn't generate standard HTML elements like <button>.Explore related questions
See similar questions with these tags.
#vaadinLoginUsernameis much cleaner and more readable than"xpath=//*[id='vaadinLoginUsername']". Regarding "playwright debugger freezes on the first locator"--does the first.fill()eventually timeout? I suggest sharing the error stack if so.