Skip to content

Commit

Permalink
Attempt to resolve flaky tests
Browse files Browse the repository at this point in the history
Tests involving successive `this.goBack()` and `this.goForward()` calls
are flaky due to timing issues:

```
× firefox on linux 5.11.0-1020-azure - FrameTests - navigating back then forward after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames next contents (0.629s)
367
    StaleElementReference: [GET http://localhost:4444/wd/hub/session/01c3334a-e303-4d29-b392-1e4f1d4d7f5c/element/a97830bd-56a4-4b7a-86a0-9543cf697716/text] The element reference of <h2> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
368
    For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/stale_element_reference.html
369
    Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'
370
    System info: host: 'fv-az214-396', ip: '10.1.0.47', os.name: 'Linux', os.arch: 'amd64', os.version: '5.11.0-1020-azure', java.version: '11.0.11'
```

In order to resolve that, this commit is more explicit with timing:
navigating forward and back will wait on `turbo:load` events to fire,
which won't occur until the page renders the cached version _and_
re-fetches the contents. Hopefully, this addresses the stale element
failures, since the referenced element won't be replaced while being
read from.

This commit introduces the `this.getVisibleTextForSelector()` helper to
combine the access-and-read action to a single Promise chain, instead of
sequential access and read commands.
  • Loading branch information
seanpdoyle committed Nov 12, 2021
1 parent e0ed694 commit 582d8a8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 45 deletions.
66 changes: 21 additions & 45 deletions src/tests/functional/frame_tests.ts
Expand Up @@ -287,103 +287,79 @@ export class FrameTests extends TurboDriveTestCase {
await this.clickSelector("#link-frame")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating turbo-frame from within with a[data-turbo-action=advance] pushes URL state"() {
await this.clickSelector("#link-nested-frame-action-advance")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating frame with a[data-turbo-action=advance] pushes URL state"() {
await this.clickSelector("#link-outside-frame-action-advance")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating frame with form[method=get][data-turbo-action=advance] pushes URL state"() {
await this.clickSelector("#form-get-frame-action-advance button")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating frame with form[method=post][data-turbo-action=advance] pushes URL state"() {
await this.clickSelector("#form-post-frame-action-advance button")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating frame with button[data-turbo-action=advance] pushes URL state"() {
await this.clickSelector("#button-frame-action-advance")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

async "test navigating back after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames previous contents"() {
await this.clickSelector("#add-turbo-action-to-frame")
await this.clickSelector("#link-frame")
await this.nextBody
await this.nextEventNamed("turbo:render")
await this.goBack()
await this.nextBody
await this.nextEventNamed("turbo:load")

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frames: #frame")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frames: #frame")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames.html")
}

async "test navigating back then forward after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames next contents"() {
await this.clickSelector("#add-turbo-action-to-frame")
await this.clickSelector("#link-frame")
await this.nextBody
await this.nextEventNamed("turbo:render")
await this.goBack()
await this.nextBody
await this.nextEventNamed("turbo:load")
await this.goForward()
await this.nextBody
await this.nextEventNamed("turbo:load")

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")

this.assert.equal(await title.getVisibleText(), "Frames")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Loaded")
this.assert.equal(await this.getVisibleTextForSelector("h1"), "Frames")
this.assert.equal(await this.getVisibleTextForSelector("#frame h2"), "Frame: Loaded")
this.assert.equal(await this.pathname, "/src/tests/fixtures/frames/frame.html")
}

Expand Down
4 changes: 4 additions & 0 deletions src/tests/helpers/functional_test_case.ts
Expand Up @@ -75,6 +75,10 @@ export class FunctionalTestCase extends InternTestCase {
return this.remote.getActiveElement().then(activeElement => activeElement.type(('\uE006'))) // ENTER
}

async getVisibleTextForSelector(selector: string): Promise<string> {
return this.querySelector(selector).then(element => element.getVisibleText())
}

async outerHTMLForSelector(selector: string): Promise<string> {
const element = await this.remote.findByCssSelector(selector)
return this.evaluate(element => element.outerHTML, element)
Expand Down

0 comments on commit 582d8a8

Please sign in to comment.