0

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!

asked Dec 5, 2025 at 12:09
3
  • Can you find an example of the site under test on vaadin.com/examples-and-demos? If not, please create such an example, since nobody has aservice.somewhere/mypage-ui/login and can't reproduce the issue you're facing. Thanks! Commented Dec 5, 2025 at 14:22
  • As an aside, xpath is discouraged. If you do need to use an id (also discouraged), #vaadinLoginUsername is 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. Commented Dec 5, 2025 at 14:29
  • @ggorlen thanks for sharing. I'll have a look at that ;-) Commented Dec 18, 2025 at 11:49

1 Answer 1

0

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.

answered Dec 5, 2025 at 15:48
Sign up to request clarification or add additional context in comments.

8 Comments

All of the page. methods here are discouraged. Prefer locators and user-visible selectors.
Those are Webcomponents. Therefore it must get the input from the light dom
Did you read those articles you linked? 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.
I'm not sure I follow, aria accessible locators should work. But thanks for the locator update--the code will now auto-wait for actionability.
Hello @simon martinelli, thanks for your response. No, I'm not a developer, I'm an automation tester. Still in the run to learn about FE automation. So I came in this company as a full stack tester and need to automate the FE that is written in vaadin. This is my first time :-) Thank you for your response. I've tried to use it in typescript adding 'await' but the buttons aren't declared so need like yours. Long story ( ;-) ) But I will continue to look for it :-)
I'm talking about non-locator 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>.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.