Skip to content

Commit 2cbfe4f

Browse files
authored
Merge pull request #354 from ujiro99/fix/e2e
Fix: Flaky tests.
2 parents bca665a + 1fe3e8e commit 2cbfe4f

4 files changed

Lines changed: 75 additions & 40 deletions

File tree

packages/extension/e2e/hub.spec.ts

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,33 @@ import { OptionsPage } from "./pages/OptionsPage"
33

44
const HUB_URL = "https://ujiro99.github.io/selection-command"
55

6+
const tryGetCommandId = (commandData: string | null): string => {
7+
if (!commandData) {
8+
throw new Error("Hub button is missing required data-command attribute")
9+
}
10+
let parsedCommand: unknown
11+
try {
12+
parsedCommand = JSON.parse(commandData)
13+
} catch (error) {
14+
throw new Error(
15+
`Failed to parse data-command JSON from Hub button: ${(error as Error).message}`,
16+
)
17+
}
18+
const commandId =
19+
typeof parsedCommand === "object" &&
20+
parsedCommand !== null &&
21+
"id" in parsedCommand &&
22+
typeof (parsedCommand as { id: unknown }).id === "string"
23+
? (parsedCommand as { id: string }).id
24+
: null
25+
if (!commandId) {
26+
throw new Error(
27+
`Parsed data-command JSON does not contain a valid "id": ${commandData}`,
28+
)
29+
}
30+
return commandId
31+
}
32+
633
test.describe("Command Hub", () => {
734
/**
835
* E2E-90: Verify that a PageAction command can be installed from the Hub.
@@ -32,18 +59,17 @@ test.describe("Command Hub", () => {
3259
.locator('button[data-command*=\'"openMode":"pageAction"\']')
3360
.filter({ hasNot: page.locator('[data-installed="true"]') })
3461
.first()
35-
36-
const isVisible = await downloadButton.isVisible()
37-
if (!isVisible) {
38-
test.skip(true, "No installable PageAction commands found on hub page")
39-
return
40-
}
41-
62+
await downloadButton.waitFor({ state: "visible", timeout: 5000 })
4263
await downloadButton.click()
43-
await page.waitForTimeout(500)
44-
45-
const commandsAfter = await getCommands()
46-
expect(commandsAfter?.length ?? 0).toBeGreaterThan(countBefore)
64+
await expect
65+
.poll(
66+
async () => {
67+
const commands = await getCommands()
68+
return (commands?.length ?? 0) > countBefore
69+
},
70+
{ timeout: 5000 },
71+
)
72+
.toBe(true)
4773
})
4874

4975
/**
@@ -72,21 +98,22 @@ test.describe("Command Hub", () => {
7298
.filter({ hasNot: page.locator('[data-installed="true"]') })
7399
.first()
74100

75-
const isVisible = await downloadButton.isVisible()
76-
if (!isVisible) {
77-
test.skip(true, "No download buttons found on hub page")
78-
return
79-
}
101+
await downloadButton.waitFor({ state: "visible", timeout: 5000 })
80102

81103
// Get the command identifier for verification
82-
const commandId = await downloadButton.getAttribute("data-command")
104+
const commandData = await downloadButton.getAttribute("data-command")
105+
tryGetCommandId(commandData)
83106

84107
await downloadButton.click()
85-
await page.waitForTimeout(500)
86-
87-
const commandsAfter = await getCommands()
88-
expect(commandsAfter?.length ?? 0).toBeGreaterThan(countBefore)
89-
expect(commandId).toBeTruthy()
108+
await expect
109+
.poll(
110+
async () => {
111+
const commands = await getCommands()
112+
return (commands?.length ?? 0) > countBefore
113+
},
114+
{ timeout: 5000 },
115+
)
116+
.toBe(true)
90117
})
91118

92119
/**
@@ -107,23 +134,27 @@ test.describe("Command Hub", () => {
107134
await page.goto(HUB_URL)
108135
await page.waitForLoadState("domcontentloaded")
109136

110-
const downloadButton = page.locator("button[data-command]").first()
111-
const isVisible = await downloadButton.isVisible()
112-
if (!isVisible) {
113-
test.skip(true, "No download buttons found on hub page")
114-
return
115-
}
137+
// Find any available download button
138+
const downloadButton = page
139+
.locator('button[data-command*=\'"openMode":"popup"\']')
140+
.filter({ hasNot: page.locator('[data-installed="true"]') })
141+
.first()
142+
143+
await downloadButton.waitFor({ state: "visible", timeout: 5000 })
116144

117145
const commandData = await downloadButton.getAttribute("data-command")
118-
const commandId = commandData ? JSON.parse(commandData).id : null
119-
await downloadButton.click()
120-
await page.waitForTimeout(500)
146+
const commandId = tryGetCommandId(commandData)
121147

122-
const commandsAfterInstall = await getCommands()
123-
const installedCommand = commandsAfterInstall?.find(
124-
(cmd) => cmd.id === commandId,
125-
)
126-
expect(installedCommand).toBeDefined()
148+
await downloadButton.click()
149+
await expect
150+
.poll(
151+
async () => {
152+
const commands = await getCommands()
153+
return commands?.find((cmd) => cmd.id === commandId) !== undefined
154+
},
155+
{ timeout: 5000 },
156+
)
157+
.toBe(true)
127158

128159
// Step 2: Delete the command via settings
129160
await optionsPage.open()
@@ -140,7 +171,7 @@ test.describe("Command Hub", () => {
140171
const restoredButton = page.locator(
141172
`button[data-command*='"id":"${commandId}"']`,
142173
)
143-
const isRestoredVisible = await restoredButton.isVisible()
144-
expect(isRestoredVisible).toBe(true)
174+
await restoredButton.waitFor({ state: "visible", timeout: 5000 })
175+
expect(restoredButton).toBeVisible()
145176
})
146177
})

packages/extension/e2e/page-action.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ test.describe("PageAction Commands", () => {
254254
context,
255255
page,
256256
}) => {
257+
test.skip(!!process.env.CI, "Do not run tests for external services in CI.")
258+
257259
await page.goto("https://www.amazon.com/")
258260
await page.waitForLoadState("domcontentloaded")
259261
await page.locator(".a-list-item .a-link-normal").first().click()

packages/extension/e2e/pages/OptionsPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,6 @@ export class OptionsPage {
238238
const reloadPromise = this.page.waitForLoadState("domcontentloaded")
239239
await okButton.click()
240240
await reloadPromise
241-
await this.page.waitForTimeout(500)
241+
await this.page.waitForTimeout(100)
242242
}
243243
}

packages/extension/e2e/url-status.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { COMMAND_URLS } from "./generated-command-urls"
1010
* The %s placeholder is replaced with "test" for each request.
1111
*/
1212

13-
test.describe.skip("E2E-URL: Default command URLs return HTTP 200", () => {
13+
test.describe("E2E-URL: Default command URLs return HTTP 200", () => {
14+
test.skip(!!process.env.CI, "Do not run tests for external services in CI.")
15+
1416
for (const { title, locale, searchUrl } of COMMAND_URLS) {
1517
const url = searchUrl.replace("%s", "test")
1618
test(`${title} (${locale}): ${url}`, async ({ request }) => {

0 commit comments

Comments
 (0)