Skip to content

Commit 384a6e3

Browse files
authored
add closed shadow dom test (#488)
1 parent 051feb9 commit 384a6e3

4 files changed

Lines changed: 57 additions & 3 deletions

File tree

abstractions/test-pages.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ type FillProperties = {
55
multiStepNextInputKey?: string;
66
preFillActions?: (page: Page) => void;
77
selector: string | ((page: Page) => Promise<Locator>);
8+
/** How autofill verification reads the filled value. "value" (default): `toHaveValue`. "text": `toHaveText` — for non-input mirrors used as side channels (e.g. inputs inside closed shadow roots that Playwright can't reach directly). */
9+
verifyAccessor?: "value" | "text";
810
/** Represents the expectation that the inline menu should not appear on the input */
911
shouldNotHaveInlineMenu?: boolean;
1012
/** Represents the expectation that the input should not be autofilled */

constants/test-pages.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,33 @@ export const testPages: PageTest[] = [
217217
},
218218
skipTests: [],
219219
},
220+
{
221+
url: `${testSiteHost}/forms/login/shadow-root-inputs-closed`,
222+
inputs: {
223+
username: {
224+
selector: '[data-mirror="username"]',
225+
verifyAccessor: "text",
226+
value: testUserName,
227+
},
228+
password: {
229+
selector: '[data-mirror="password"]',
230+
verifyAccessor: "text",
231+
value: "fakeShadowRootInputsClosedPassword",
232+
},
233+
},
234+
actions: {
235+
submit: async (page) =>
236+
await page.getByRole("button", { name: "Login", exact: true }).click(),
237+
},
238+
skipTests: [
239+
// these tests require focusing an input to perform autofill. Playwright cannot focus these
240+
// because it cannot locate elements in closed shadow roots
241+
// see: https://playwright.dev/docs/locators#locate-in-shadow-dom
242+
TestNames.InlineMenuAutofill,
243+
TestNames.NewCredentialsNotification,
244+
TestNames.PasswordUpdateNotification,
245+
],
246+
},
220247
// @TODO add test for /forms/create/create-account
221248
// @TODO add test for /forms/create/create-account-extended/
222249
// Card and Identity Ciphers currently cannot be autofilled through the same mechanism that Login Ciphers are. This is because of how we handle messaging for autofilling login items. The extension will need to be updated to handle these types of Ciphers.

constants/vault-ciphers.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ export const pageCiphers: PageCipher[] = [
132132
},
133133
{
134134
cipherType: CipherType.Login,
135-
url: `${testSiteHost}/forms/login/shadow-root-inputs`,
135+
// Trailing slash distinguishes from `/shadow-root-inputs-closed`; both pages are served with trailing slashes by Docusaurus.
136+
url: `${testSiteHost}/forms/login/shadow-root-inputs/`,
136137
uriMatchType: UriMatchType.StartsWith,
137138
fields: {
138139
username: {
@@ -143,6 +144,19 @@ export const pageCiphers: PageCipher[] = [
143144
},
144145
},
145146
},
147+
{
148+
cipherType: CipherType.Login,
149+
url: `${testSiteHost}/forms/login/shadow-root-inputs-closed`,
150+
uriMatchType: UriMatchType.StartsWith,
151+
fields: {
152+
username: {
153+
value: testUserName,
154+
},
155+
password: {
156+
value: "fakeShadowRootInputsClosedPassword",
157+
},
158+
},
159+
},
146160
{
147161
cipherType: CipherType.Login,
148162
url: `${testSiteHost}/forms/create/create-account`,

tests/static/autofill-forms.spec.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ test.describe("Extension autofills forms when triggered", () => {
7474
typeof firstInputSelector === "string"
7575
? await testPage.locator(firstInputSelector).first()
7676
: await firstInputSelector(testPage);
77-
await firstInputElement.waitFor(defaultWaitForOptions);
77+
// text-mode mirrors have no rendered size until autofill populates them, so wait for attachment, not visibility
78+
await firstInputElement.waitFor(
79+
firstInput.verifyAccessor === "text"
80+
? { ...defaultWaitForOptions, state: "attached" }
81+
: defaultWaitForOptions,
82+
);
7883

7984
await doAutofill(background);
8085

@@ -95,7 +100,13 @@ test.describe("Extension autofills forms when triggered", () => {
95100
? ""
96101
: currentInput.value;
97102

98-
await expect(currentInputSelectedElement).toHaveValue(expectedValue);
103+
if (currentInput.verifyAccessor === "text") {
104+
await expect(currentInputSelectedElement).toHaveText(expectedValue);
105+
} else {
106+
await expect(currentInputSelectedElement).toHaveValue(
107+
expectedValue,
108+
);
109+
}
99110

100111
await testPage.screenshot({
101112
fullPage: true,

0 commit comments

Comments
 (0)