Skip to content

Commit 5e8fe4e

Browse files
code-asherAkash Satheesan
authored andcommitted
Cancel current menu navigation on retry
1 parent 7e3bb46 commit 5e8fe4e

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

test/e2e/models/CodeServer.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ interface CodeServerProcess {
1212
address: string
1313
}
1414

15+
class CancelToken {
16+
private _canceled = false
17+
public canceled(): boolean {
18+
return this._canceled
19+
}
20+
public cancel(): void {
21+
this._canceled = true
22+
}
23+
}
24+
1525
/**
1626
* Class for spawning and managing code-server.
1727
*/
@@ -247,11 +257,27 @@ export class CodeServerPage {
247257
* trying.
248258
*/
249259
async navigateMenus(menus: string[]) {
250-
const navigate = async () => {
251-
await this.page.waitForSelector(`${menuSelector}:focus-within`)
260+
const navigate = async (cancelToken: CancelToken) => {
261+
const steps: Array<() => Promise<unknown>> = [() => this.page.waitForSelector(`${menuSelector}:focus-within`)]
252262
for (const menu of menus) {
253-
await this.page.hover(`text=${menu}`)
254-
await this.page.click(`text=${menu}`)
263+
// Normally these will wait for the item to be visible and then execute
264+
// the action. The problem is that if the menu closes these will still
265+
// be waiting and continue to execute once the menu is visible again,
266+
// potentially conflicting with the new set of navigations (for example
267+
// if the old promise clicks logout before the new one can). By
268+
// splitting them into two steps each we can cancel before running the
269+
// action.
270+
steps.push(() => this.page.hover(`text=${menu}`, { trial: true }))
271+
steps.push(() => this.page.hover(`text=${menu}`, { force: true }))
272+
steps.push(() => this.page.click(`text=${menu}`, { trial: true }))
273+
steps.push(() => this.page.click(`text=${menu}`, { force: true }))
274+
}
275+
for (const step of steps) {
276+
await step()
277+
if (cancelToken.canceled()) {
278+
this.codeServer.logger.debug("menu navigation canceled")
279+
return false
280+
}
255281
}
256282
return true
257283
}
@@ -266,10 +292,15 @@ export class CodeServerPage {
266292
// TODO: Starting in 1.57 something closes the menu after opening it if we
267293
// open it too soon. To counter that we'll watch for when the menu loses
268294
// focus and when/if it does we'll try again.
295+
// I tried using the classic menu but it doesn't show up at all for some
296+
// reason. I also tried toggle but the menu disappears after toggling.
269297
let retryCount = 0
270-
while (!(await Promise.race([open(), navigate()]))) {
298+
let cancelToken = new CancelToken()
299+
while (!(await Promise.race([open(), navigate(cancelToken)]))) {
271300
this.codeServer.logger.debug("menu was closed, retrying")
272301
++retryCount
302+
cancelToken.cancel()
303+
cancelToken = new CancelToken()
273304
}
274305

275306
this.codeServer.logger.debug(`menu navigation retries: ${retryCount}`)

0 commit comments

Comments
 (0)