diff --git a/package.json b/package.json index 214ddee8e..486c15bc2 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "@web/test-runner-playwright": "^0.9.0", "arg": "^5.0.1", "body-parser": "^1.20.1", - "chai": "~4.3.4", "eslint": "^8.13.0", "express": "^4.18.2", "multer": "^1.4.2", diff --git a/src/tests/functional/async_script_tests.js b/src/tests/functional/async_script_tests.js index f2e27a3a9..a0d1a35a8 100644 --- a/src/tests/functional/async_script_tests.js +++ b/src/tests/functional/async_script_tests.js @@ -1,5 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { readEventLogs, visitAction } from "../helpers/page" test.beforeEach(async ({ page }) => { @@ -10,11 +9,11 @@ test.beforeEach(async ({ page }) => { test("does not emit turbo:load when loaded asynchronously after DOMContentLoaded", async ({ page }) => { const events = await readEventLogs(page) - assert.deepEqual(events, []) + expect(events).toEqual([]) }) test("following a link when loaded asynchronously after DOMContentLoaded", async ({ page }) => { await page.click("#async-link") - assert.equal(await visitAction(page), "advance") + expect(await visitAction(page)).toEqual("advance") }) diff --git a/src/tests/functional/autofocus_tests.js b/src/tests/functional/autofocus_tests.js index 011562ceb..67183e0e6 100644 --- a/src/tests/functional/autofocus_tests.js +++ b/src/tests/functional/autofocus_tests.js @@ -1,150 +1,88 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { hasSelector, nextBeat } from "../helpers/page" +import { expect, test } from "@playwright/test" test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/autofocus.html") }) test("autofocus first autofocus element on load", async ({ page }) => { - await nextBeat() - assert.ok( - await hasSelector(page, "#first-autofocus-element:focus"), + await expect( + page.locator("#first-autofocus-element"), "focuses the first [autofocus] element on the page" - ) - assert.notOk( - await hasSelector(page, "#second-autofocus-element:focus"), + ).toBeFocused() + await expect( + page.locator("#second-autofocus-element"), "focuses the first [autofocus] element on the page" - ) + ).not.toBeFocused() }) test("autofocus first [autofocus] element on visit", async ({ page }) => { await page.goto("/src/tests/fixtures/navigation.html") await page.click("#autofocus-link") - await nextBeat() - assert.ok( - await hasSelector(page, "#first-autofocus-element:focus"), - "focuses the first [autofocus] element on the page" - ) - assert.notOk( - await hasSelector(page, "#second-autofocus-element:focus"), - "focuses the first [autofocus] element on the page" - ) + await expect(page.locator("#first-autofocus-element")).toBeFocused() + await expect(page.locator("#second-autofocus-element")).not.toBeFocused() }) test("navigating a frame with a descendant link autofocuses [autofocus]:first-of-type", async ({ page }) => { await page.click("#frame-inner-link") - await nextBeat() - - assert.ok( - await hasSelector(page, "#frames-form-first-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) - assert.notOk( - await hasSelector(page, "#frames-form-second-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) + + await expect(page.locator("#frames-form-first-autofocus-element")).toBeFocused() + await expect(page.locator("#frames-form-second-autofocus-element")).not.toBeFocused() }) test("autofocus visible [autofocus] element on visit with inert elements", async ({ page }) => { await page.click("#autofocus-inert-link") - await nextBeat() - - assert.notOk( - await hasSelector(page, "#dialog-autofocus-element:focus"), - "autofocus element is ignored in a closed dialog" - ) - assert.notOk( - await hasSelector(page, "#details-autofocus-element:focus"), - "autofocus element is ignored in a closed details" - ) - assert.notOk( - await hasSelector(page, "#hidden-autofocus-element:focus"), - "autofocus element is ignored in a hidden div" - ) - assert.notOk( - await hasSelector(page, "#inert-autofocus-element:focus"), - "autofocus element is ignored in an inert div" - ) - assert.notOk( - await hasSelector(page, "#disabled-autofocus-element:focus"), - "autofocus element is ignored when disabled" - ) - assert.ok( - await hasSelector(page, "#visible-autofocus-element:focus"), - "focuses the visible [autofocus] element on the page" - ) + + await expect(page.locator("#dialog-autofocus-element")).not.toBeFocused() + await expect(page.locator("#details-autofocus-element")).not.toBeFocused() + await expect(page.locator("#hidden-autofocus-element")).not.toBeFocused() + await expect(page.locator("#inert-autofocus-element")).not.toBeFocused() + await expect(page.locator("#disabled-autofocus-element")).not.toBeFocused() + await expect(page.locator("#visible-autofocus-element")).toBeFocused() }) test("navigating a frame with a link targeting the frame autofocuses [autofocus]:first-of-type", async ({ page }) => { await page.click("#frame-outer-link") - await nextBeat() - - assert.ok( - await hasSelector(page, "#frames-form-first-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) - assert.notOk( - await hasSelector(page, "#frames-form-second-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) + + await expect(page.locator("#frames-form-first-autofocus-element")).toBeFocused() + await expect(page.locator("#frames-form-second-autofocus-element")).not.toBeFocused() }) test("navigating a frame with a turbo-frame targeting the frame autofocuses [autofocus]:first-of-type", async ({ page }) => { await page.click("#drives-frame-target-link") - await nextBeat() - - assert.ok( - await hasSelector(page, "#frames-form-first-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) - assert.notOk( - await hasSelector(page, "#frames-form-second-autofocus-element:focus"), - "focuses the first [autofocus] element in frame" - ) + + await expect(page.locator("#frames-form-first-autofocus-element")).toBeFocused() + await expect(page.locator("#frames-form-second-autofocus-element")).not.toBeFocused() }) test("receiving a Turbo Stream message with an [autofocus] element when the activeElement is the document", async ({ page }) => { await page.evaluate(() => { - if (document.activeElement instanceof HTMLElement) { - document.activeElement.blur() - } + document.activeElement.blur() window.Turbo.renderStreamMessage(` `) }) - await nextBeat() - assert.ok( - await hasSelector(page, "#autofocus-from-stream:focus"), - "focuses the [autofocus] element in from the turbo-stream" - ) + await expect(page.locator("#autofocus-from-stream")).toBeFocused() }) test("autofocus from a Turbo Stream message does not leak a placeholder [id]", async ({ page }) => { await page.evaluate(() => { - if (document.activeElement instanceof HTMLElement) { - document.activeElement.blur() - } + document.activeElement.blur() window.Turbo.renderStreamMessage(` `) }) - await nextBeat() - assert.ok( - await hasSelector(page, "#container-from-stream input:focus"), - "focuses the [autofocus] element in from the turbo-stream" - ) + await expect(page.locator("#container-from-stream input")).toBeFocused() }) test("receiving a Turbo Stream message with an [autofocus] element when an element within the document has focus", async ({ page }) => { @@ -155,10 +93,6 @@ test("receiving a Turbo Stream message with an [autofocus] element when an eleme `) }) - await nextBeat() - assert.ok( - await hasSelector(page, "#first-autofocus-element:focus"), - "focuses the first [autofocus] element on the page" - ) + await expect(page.locator("#first-autofocus-element")).toBeFocused() }) diff --git a/src/tests/functional/cache_observer_tests.js b/src/tests/functional/cache_observer_tests.js index 64d3c8c5d..c6d1422f9 100644 --- a/src/tests/functional/cache_observer_tests.js +++ b/src/tests/functional/cache_observer_tests.js @@ -1,37 +1,33 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { hasSelector, nextBody } from "../helpers/page" +import { expect, test } from "@playwright/test" +import { nextEventNamed } from "../helpers/page" test("removes temporary elements", async ({ page }) => { await page.goto("/src/tests/fixtures/cache_observer.html") - assert.equal(await page.textContent("#temporary"), "data-turbo-temporary") + await expect(page.locator("#temporary")).toHaveText("data-turbo-temporary") await page.click("#link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await page.goBack() - await nextBody(page) - assert.notOk(await hasSelector(page, "#temporary")) + await expect(page.locator("#temporary")).not.toBeVisible() }) test("removes temporary elements with deprecated turbo-cache=false selector", async ({ page }) => { await page.goto("/src/tests/fixtures/cache_observer.html") - assert.equal(await page.textContent("#temporary-with-deprecated-selector"), "data-turbo-cache=false") + await expect(page.locator("#temporary-with-deprecated-selector")).toHaveText("data-turbo-cache=false") await page.click("#link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await page.goBack() - await nextBody(page) - assert.notOk(await hasSelector(page, "#temporary-with-deprecated-selector")) + await expect(page.locator("#temporary-with-deprecated-selector")).not.toBeVisible() }) test("following a redirect renders [data-turbo-temporary] elements before the cache removes", async ({ page }) => { await page.goto("/src/tests/fixtures/navigation.html") await page.click("#redirect-to-cache-observer") - await nextBody(page) - assert.equal(await page.textContent("#temporary"), "data-turbo-temporary") + await expect(page.locator("#temporary")).toHaveText("data-turbo-temporary") }) diff --git a/src/tests/functional/drive_disabled_tests.js b/src/tests/functional/drive_disabled_tests.js index 1b4181bae..5a7919464 100644 --- a/src/tests/functional/drive_disabled_tests.js +++ b/src/tests/functional/drive_disabled_tests.js @@ -1,8 +1,8 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { getFromLocalStorage, - nextBody, + nextBeat, + nextEventNamed, nextEventOnTarget, pathname, searchParams, @@ -18,30 +18,30 @@ test.beforeEach(async ({ page }) => { test("drive disabled by default; click normal link", async ({ page }) => { await page.click("#drive_disabled") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), path) - assert.equal(await visitAction(page), "load") + expect(pathname(page.url())).toEqual(path) + expect(await visitAction(page)).toEqual("load") }) test("drive disabled by default; click link inside data-turbo='true'", async ({ page }) => { await page.click("#drive_enabled") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), path) - assert.equal(await visitAction(page), "advance") + expect(pathname(page.url())).toEqual(path) + expect(await visitAction(page)).toEqual("advance") }) test("drive disabled by default; submit form inside data-turbo='true'", async ({ page }) => { await setLocalStorageFromEvent(page, "turbo:submit-start", "formSubmitted", "true") await page.click("#no_submitter_drive_enabled a#requestSubmit") - await nextBody(page) + await nextBeat() - assert.ok(await getFromLocalStorage(page, "formSubmitted")) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(await visitAction(page), "advance") - assert.equal(await searchParams(page.url()).get("greeting"), "Hello from a redirect") + expect(await getFromLocalStorage(page, "formSubmitted")).toEqual("true") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await visitAction(page)).toEqual("advance") + expect(await searchParams(page.url()).get("greeting")).toEqual("Hello from a redirect") }) test("drive disabled by default; links within navigate with Turbo", async ({ page }) => { diff --git a/src/tests/functional/drive_tests.js b/src/tests/functional/drive_tests.js index 68980aa80..909778af9 100644 --- a/src/tests/functional/drive_tests.js +++ b/src/tests/functional/drive_tests.js @@ -1,6 +1,5 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { nextBody, pathname, visitAction } from "../helpers/page" +import { expect, test } from "@playwright/test" +import { nextEventNamed, pathname, visitAction } from "../helpers/page" const path = "/src/tests/fixtures/drive.html" @@ -10,8 +9,8 @@ test.beforeEach(async ({ page }) => { test("drive enabled by default; click normal link", async ({ page }) => { await page.click("#drive_enabled") - await nextBody(page) - assert.equal(pathname(page.url()), path) + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual(path) }) test("drive to external link", async ({ page }) => { @@ -20,16 +19,14 @@ test("drive to external link", async ({ page }) => { }) await page.click("#drive_enabled_external") - await nextBody(page) - assert.equal(await page.evaluate(() => window.location.href), "https://example.com/") - assert.equal(await page.textContent("body"), "Hello from the outside world") + await expect(page).toHaveURL("https://example.com/") + await expect(page.locator("body")).toHaveText("Hello from the outside world") }) test("drive enabled by default; click link inside data-turbo='false'", async ({ page }) => { await page.click("#drive_disabled") - await nextBody(page) - assert.equal(pathname(page.url()), path) - assert.equal(await visitAction(page), "load") + await expect(page).toHaveURL(path) + expect(await visitAction(page)).toEqual("load") }) diff --git a/src/tests/functional/drive_view_transition_tests.js b/src/tests/functional/drive_view_transition_tests.js index e4c9f48fd..ecce54d7b 100644 --- a/src/tests/functional/drive_view_transition_tests.js +++ b/src/tests/functional/drive_view_transition_tests.js @@ -1,11 +1,12 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { nextBody } from "../helpers/page" +import { expect, test } from "@playwright/test" +import { nextBeat } from "../helpers/page" test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/transitions/left.html") await page.evaluate(` + window.startViewTransitionCalled = false + document.startViewTransition = (callback) => { window.startViewTransitionCalled = true callback() @@ -14,17 +15,17 @@ test.beforeEach(async ({ page }) => { }) test("navigating triggers the view transition", async ({ page }) => { - await page.locator("#go-right").click() - await nextBody(page) + await page.click("#go-right") + await nextBeat() const called = await page.evaluate(`window.startViewTransitionCalled`) - assert.isTrue(called) + expect(called).toEqual(true) }) test("navigating does not trigger a view transition when meta tag not present", async ({ page }) => { - await page.locator("#go-other").click() - await nextBody(page) + await page.click("#go-other") + await nextBeat() const called = await page.evaluate(`window.startViewTransitionCalled`) - assert.isUndefined(called) + expect(called).toEqual(false) }) diff --git a/src/tests/functional/form_mode_tests.js b/src/tests/functional/form_mode_tests.js index e642c2905..878cbd62e 100644 --- a/src/tests/functional/form_mode_tests.js +++ b/src/tests/functional/form_mode_tests.js @@ -1,68 +1,67 @@ -import { test } from "@playwright/test" +import { expect, test } from "@playwright/test" import { getFromLocalStorage, setLocalStorageFromEvent } from "../helpers/page" -import { assert } from "chai" test("form submission with form mode off", async ({ page }) => { await gotoPageWithFormMode(page, "off") await page.click("#turbo-enabled-form button") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission without submitter with form mode off", async ({ page }) => { await gotoPageWithFormMode(page, "off") await page.press("#turbo-enabled-form-without-submitter [type=text]", "Enter") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission with form mode off from submitter outside form", async ({ page }) => { await gotoPageWithFormMode(page, "off") await page.click("button[form=turbo-enabled-form]") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission with form mode optin and form not enabled", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.click("#form button") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission without submitter with form mode optin and form not enabled", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.press("#form-without-submitter [type=text]", "Enter") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission with form mode optin and form not enabled from submitter outside form", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.click("button[form=form]") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission with form mode optin and form enabled", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.click("#turbo-enabled-form button") - assert.ok(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).toEqual("true") }) test("form submission without submitter with form mode optin and form enabled", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.press("#turbo-enabled-form-without-submitter [type=text]", "Enter") - assert.ok(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).toEqual("true") }) test("form submission with form mode optin and form enabled from submitter outside form", async ({ page }) => { await gotoPageWithFormMode(page, "optin") await page.click("button[form=turbo-enabled-form]") - assert.ok(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).toEqual("true") }) async function gotoPageWithFormMode(page, formMode) { diff --git a/src/tests/functional/form_submission_tests.js b/src/tests/functional/form_submission_tests.js index 987038448..ab8ff3947 100644 --- a/src/tests/functional/form_submission_tests.js +++ b/src/tests/functional/form_submission_tests.js @@ -1,5 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { getFromLocalStorage, getSearchParam, @@ -18,9 +17,7 @@ import { search, searchParams, setLocalStorageFromEvent, - visitAction, - waitUntilSelector, - waitUntilNoSelector + visitAction } from "../helpers/page" test.beforeEach(async ({ page }) => { @@ -34,115 +31,110 @@ test("standard form submission renders a progress bar", async ({ page }) => { await page.evaluate(() => window.Turbo.setProgressBarDelay(0)) await page.click("#standard form.sleep input[type=submit]") - await waitUntilSelector(page, ".turbo-progress-bar") - assert.ok(await hasSelector(page, ".turbo-progress-bar"), "displays progress bar") - - await nextBody(page) - await waitUntilNoSelector(page, ".turbo-progress-bar") - - assert.notOk(await hasSelector(page, ".turbo-progress-bar"), "hides progress bar") + await expect(page.locator(".turbo-progress-bar")).toBeVisible() + await expect(page.locator(".turbo-progress-bar")).not.toBeVisible() }) test("form submission with confirmation confirmed", async ({ page }) => { page.on("dialog", (alert) => { - assert.equal(alert.message(), "Are you sure?") + expect(alert.message()).toEqual("Are you sure?") alert.accept() }) await page.click("#standard form.confirm input[type=submit]") await nextEventNamed(page, "turbo:load") - assert.ok(await formSubmitStarted(page)) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") + expect(await formSubmitStarted(page)).toEqual("true") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") }) test("form submission with confirmation cancelled", async ({ page }) => { page.on("dialog", (alert) => { - assert.equal(alert.message(), "Are you sure?") + expect(alert.message()).toEqual("Are you sure?") alert.dismiss() }) await page.click("#standard form.confirm input[type=submit]") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toEqual("true") }) test("form submission with secondary submitter click - confirmation confirmed", async ({ page }) => { page.on("dialog", (alert) => { - assert.equal(alert.message(), "Are you really sure?") + expect(alert.message()).toEqual("Are you really sure?") alert.accept() }) await page.click("#standard form.confirm #secondary_submitter") await nextEventNamed(page, "turbo:load") - assert.ok(await formSubmitStarted(page)) - assert.equal(await pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") - assert.equal(getSearchParam(page.url(), "greeting"), "secondary_submitter") + expect(await formSubmitStarted(page)).toEqual("true") + expect(await pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") + expect(getSearchParam(page.url(), "greeting")).toEqual("secondary_submitter") }) test("form submission with secondary submitter click - confirmation cancelled", async ({ page }) => { page.on("dialog", (alert) => { - assert.equal(alert.message(), "Are you really sure?") + expect(alert.message()).toEqual("Are you really sure?") alert.dismiss() }) await page.click("#standard form.confirm #secondary_submitter") - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toEqual("true") }) test("from submission with confirmation overridden", async ({ page }) => { page.on("dialog", (alert) => { - assert.equal(alert.message(), "Overridden message") + expect(alert.message()).toEqual("Overridden message") alert.accept() }) await page.evaluate(() => window.Turbo.setConfirmMethod(() => Promise.resolve(confirm("Overridden message")))) await page.click("#standard form.confirm input[type=submit]") - assert.ok(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).toEqual("true") }) test("standard form submission does not render a progress bar before expiring the delay", async ({ page }) => { await page.evaluate(() => window.Turbo.setProgressBarDelay(500)) await page.click("#standard form.redirect input[type=submit]") - assert.notOk(await hasSelector(page, ".turbo-progress-bar"), "does not show progress bar before delay") + await expect(page.locator(".turbo-progress-bar")).not.toBeVisible() }) test("standard POST form submission with redirect response", async ({ page }) => { await page.click("#standard form.redirect input[type=submit]") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.ok(await formSubmitStarted(page)) - assert.equal(await pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(await visitAction(page), "advance") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello from a redirect") - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - "true", - "sets [aria-busy] on the document element" + expect(await formSubmitStarted(page)).toEqual("true") + expect(await pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await visitAction(page)).toEqual("advance") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello from a redirect") + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + "true" ) - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - null, - "removes [aria-busy] from the document element" + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + null ) }) test("standard POST form submission events", async ({ page }) => { await page.click("#standard-post-form-submit") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:before-visit") await nextEventNamed(page, "turbo:visit") @@ -160,10 +152,9 @@ test("supports transforming a POST submission to a GET in a turbo:submit-start l })) ) await page.click("#standard form[method=post] [type=submit]") - await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "One", "overrides the method and action") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello, from an event listener") + await expect(page.locator("h1")).toHaveText("One") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello, from an event listener") }) test("supports transforming a GET submission to a POST in a turbo:submit-start listener", async ({ page }) => { @@ -175,10 +166,9 @@ test("supports transforming a GET submission to a POST in a turbo:submit-start l })) ) await page.click("#standard form[method=get] [type=submit]") - await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "One", "overrides the method and action") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello, from an event listener") + await expect(page.locator("h1")).toHaveText("One") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello, from an event listener") }) test("supports modifying the submission in a turbo:before-fetch-request listener", async ({ page }) => { @@ -191,49 +181,57 @@ test("supports modifying the submission in a turbo:before-fetch-request listener })) ) await page.click("#standard form[method=post] [type=submit]") + + await expect(page.locator("h1")).toHaveText("One") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello from a redirect") +}) + +test("standard POST form submission merges values from both searchParams and body", async ({ page }) => { + await page.click("#form-action-post-redirect-self-q-b") await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "One", "overrides the method and action") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello from a redirect") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "q")).toEqual("b") + expect(getSearchParam(page.url(), "sort")).toEqual("asc") }) test("standard POST form submission merges values from both searchParams and body", async ({ page }) => { await page.click("#form-action-post-redirect-self-q-b") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "q"), "b") - assert.equal(getSearchParam(page.url(), "sort"), "asc") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "q")).toEqual("b") + expect(getSearchParam(page.url(), "sort")).toEqual("asc") }) test("standard POST form submission toggles submitter [disabled] attribute", async ({ page }) => { await page.click("#standard-post-form-submit") - assert.equal( - await nextAttributeMutationNamed(page, "standard-post-form-submit", "disabled"), - "", - "sets [disabled] on the submitter" + expect( + await nextAttributeMutationNamed(page, "standard-post-form-submit", "disabled") + ).toEqual( + "" ) - assert.equal( - await nextAttributeMutationNamed(page, "standard-post-form-submit", "disabled"), - null, - "removes [disabled] from the submitter" + expect( + await nextAttributeMutationNamed(page, "standard-post-form-submit", "disabled") + ).toEqual( + null ) }) test("replaces input value with data-turbo-submits-with on form submission", async ({ page }) => { - page.click("#submits-with-form-input") + await page.click("#submits-with-form-input") - assert.equal( - await nextAttributeMutationNamed(page, "submits-with-form-input", "value"), - "Saving...", - "sets data-turbo-submits-with on the submitter" + expect( + await nextAttributeMutationNamed(page, "submits-with-form-input", "value") + ).toEqual( + "Saving..." ) - assert.equal( - await nextAttributeMutationNamed(page, "submits-with-form-input", "value"), - "Save", - "restores the original submitter text value" + expect( + await nextAttributeMutationNamed(page, "submits-with-form-input", "value") + ).toEqual( + "Save" ) }) @@ -241,17 +239,17 @@ test("replaces button innerHTML with data-turbo-submits-with on form submission" await page.click("#submits-with-form-button") await nextEventNamed(page, "turbo:submit-start") - assert.equal( - await page.textContent("#submits-with-form-button"), - "Saving...", - "sets data-turbo-submits-with on the submitter" + await expect( + page.locator("#submits-with-form-button") + ).toHaveText( + "Saving..." ) await nextEventNamed(page, "turbo:submit-end") - assert.equal( - await page.textContent("#submits-with-form-button"), - "Save", - "sets data-turbo-submits-with on the submitter" + await expect( + page.locator("#submits-with-form-button") + ).toHaveText( + "Save" ) }) @@ -259,44 +257,41 @@ test("standard GET form submission", async ({ page }) => { await page.click("#standard form.greeting input[type=submit]") await nextBody(page) - assert.ok(await formSubmitStarted(page)) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello from a form") - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - "true", - "sets [aria-busy] on the document element" + expect(await formSubmitStarted(page)).toEqual("true") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello from a form") + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + "true" ) - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - null, - "removes [aria-busy] from the document element" + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + null ) }) test("standard GET HTMLFormElement.requestSubmit() with Turbo Action", async ({ page }) => { - await page.evaluate(() => { - const formControl = document.querySelector("#external-select") - + const select = await page.locator("#external-select") + await select.evaluate((formControl) => { if (formControl && formControl.form) formControl.form.requestSubmit() }) await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "Form", "Retains original page state") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame", "navigates #hello turbo frame") - assert.equal(await visitAction(page), "replace", "reads Turbo Action from
") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/hello.html", "promotes frame navigation to page Visit") - assert.equal(getSearchParam(page.url(), "greeting"), "Hello from a replace Visit", "encodes into request") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") + expect(await visitAction(page)).toEqual("replace") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/hello.html") + expect(getSearchParam(page.url(), "greeting")).toEqual("Hello from a replace Visit") }) test("GET HTMLFormElement.requestSubmit() triggered by javascript", async ({ page }) => { await page.click("#request-submit-trigger") - await nextEventNamed(page, "turbo:load") - - assert.notEqual(pathname(page.url()), "/src/tests/fixtures/one.html", "SubmitEvent was triggered without a submitter") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame", "navigates #hello turbo frame") + expect(pathname(page.url())).not.toEqual("/src/tests/fixtures/one.html") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("standard GET form submission with [data-turbo-stream] declared on the form", async ({ page }) => { @@ -304,7 +299,7 @@ test("standard GET form submission with [data-turbo-stream] declared on the form const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") }) test("standard GET form submission with [data-turbo-stream] declared on submitter", async ({ page }) => { @@ -312,21 +307,21 @@ test("standard GET form submission with [data-turbo-stream] declared on submitte const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") }) test("standard GET form submission events", async ({ page }) => { await page.click("#standard-get-form-submit") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.notOk(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) + expect(fetchOptions.headers["Accept"]).not.toContain("text/vnd.turbo-stream.html") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:before-visit") await nextEventNamed(page, "turbo:visit") @@ -340,54 +335,54 @@ test("standard GET form submission does not incorporate the current page's URLSe page }) => { await page.click("#form-action-self-sort") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(search(page.url()), "?sort=asc") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(search(page.url())).toEqual("?sort=asc") await page.click("#form-action-none-q-a") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(search(page.url()), "?q=a", "navigates without omitted keys") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(search(page.url())).toEqual("?q=a") }) test("standard GET form submission does not merge values into the [action] attribute", async ({ page }) => { await page.click("#form-action-self-sort") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(await pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(await search(page.url()), "?sort=asc") + expect(await pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await search(page.url())).toEqual("?sort=asc") await page.click("#form-action-self-q-b") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(await pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(await search(page.url()), "?q=b", "navigates without omitted keys") + expect(await pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await search(page.url())).toEqual("?q=b") }) test("standard GET form submission omits the [action] value's URLSearchParams from the submission", async ({ page }) => { await page.click("#form-action-self-submit") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(search(page.url()), "") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(search(page.url())).toEqual("") }) test("standard GET form submission toggles submitter [disabled] attribute", async ({ page }) => { await page.click("#standard-get-form-submit") - assert.equal( - await nextAttributeMutationNamed(page, "standard-get-form-submit", "disabled"), - "", - "sets [disabled] on the submitter" + expect( + await nextAttributeMutationNamed(page, "standard-get-form-submit", "disabled") + ).toEqual( + "" ) - assert.equal( - await nextAttributeMutationNamed(page, "standard-get-form-submit", "disabled"), - null, - "removes [disabled] from the submitter" + expect( + await nextAttributeMutationNamed(page, "standard-get-form-submit", "disabled") + ).toEqual( + null ) }) @@ -396,28 +391,26 @@ test("standard GET form submission appending keys", async ({ page }) => { await page.click("#standard form.conflicting-values input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "2") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("2") }) test("standard form submission with empty created response", async ({ page }) => { const htmlBefore = await outerHTMLForSelector(page, "body") - const button = await page.locator("#standard form.created input[type=submit]") - await button.click() + await page.click("#standard form.created input[type=submit]") await nextBeat() const htmlAfter = await outerHTMLForSelector(page, "body") - assert.equal(htmlAfter, htmlBefore) + expect(htmlAfter).toEqual(htmlBefore) }) test("standard form submission with empty no-content response", async ({ page }) => { const htmlBefore = await outerHTMLForSelector(page, "body") - const button = await page.locator("#standard form.no-content input[type=submit]") - await button.click() + await page.click("#standard form.no-content input[type=submit]") await nextBeat() const htmlAfter = await outerHTMLForSelector(page, "body") - assert.equal(htmlAfter, htmlBefore) + expect(htmlAfter).toEqual(htmlBefore) }) test("standard POST form submission with multipart/form-data enctype", async ({ page }) => { @@ -425,7 +418,7 @@ test("standard POST form submission with multipart/form-data enctype", async ({ await nextBeat() const enctype = getSearchParam(page.url(), "enctype") - assert.ok(enctype?.startsWith("multipart/form-data"), "submits a multipart/form-data request") + expect(enctype).toContain("multipart/form-data") }) test("standard GET form submission ignores enctype", async ({ page }) => { @@ -433,7 +426,7 @@ test("standard GET form submission ignores enctype", async ({ page }) => { await nextBeat() const enctype = getSearchParam(page.url(), "enctype") - assert.notOk(enctype, "GET form submissions ignore enctype") + expect(enctype).not.toBe() }) test("standard POST form submission without an enctype", async ({ page }) => { @@ -441,31 +434,28 @@ test("standard POST form submission without an enctype", async ({ page }) => { await nextBeat() const enctype = getSearchParam(page.url(), "enctype") - assert.ok( - enctype?.startsWith("application/x-www-form-urlencoded"), - "submits a application/x-www-form-urlencoded request" - ) + expect(enctype).toContain("application/x-www-form-urlencoded") }) test("no-action form submission with single parameter", async ({ page }) => { await page.click("#no-action form.single input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "1") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("1") await page.click("#no-action form.single input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "1") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("1") await page.goto("/src/tests/fixtures/form.html?query=2") await page.click("#no-action form.single input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "1") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("1") }) test("no-action form submission with multiple parameters", async ({ page }) => { @@ -473,87 +463,81 @@ test("no-action form submission with multiple parameters", async ({ page }) => { await page.click("#no-action form.multiple input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.deepEqual(searchParams(page.url()).getAll("query"), ["1", "2"]) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(searchParams(page.url()).getAll("query")).toEqual(["1", "2"]) await page.click("#no-action form.multiple input[type=submit]") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.deepEqual(searchParams(page.url()).getAll("query"), ["1", "2"]) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(searchParams(page.url()).getAll("query")).toEqual(["1", "2"]) }) test("no-action form submission submitter parameters", async ({ page }) => { await page.click("#no-action form.button-param [type=submit]") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "1") - assert.deepEqual(searchParams(page.url()).getAll("button"), [""]) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("1") + expect(searchParams(page.url()).getAll("button")).toEqual([""]) await page.click("#no-action form.button-param [type=submit]") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "query"), "1") - assert.deepEqual(searchParams(page.url()).getAll("button"), [""]) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "query")).toEqual("1") + expect(searchParams(page.url()).getAll("button")).toEqual([""]) }) test("submitter with blank formaction submits to the current page", async ({ page }) => { await page.click("#blank-formaction button") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.ok(await hasSelector(page, "#blank-formaction"), "overrides form[action] navigation") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + await expect(page.locator("#blank-formaction")).toBeVisible() }) test("input named action with no action attribute", async ({ page }) => { await page.click("#action-input form.no-action [type=submit]") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.equal(getSearchParam(page.url(), "action"), "1") - assert.equal(getSearchParam(page.url(), "query"), "1") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(getSearchParam(page.url(), "action")).toEqual("1") + expect(getSearchParam(page.url(), "query")).toEqual("1") }) test("input named action with action attribute", async ({ page }) => { await page.click("#action-input form.action [type=submit]") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(getSearchParam(page.url(), "action"), "1") - assert.equal(getSearchParam(page.url(), "query"), "1") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(getSearchParam(page.url(), "action")).toEqual("1") + expect(getSearchParam(page.url(), "query")).toEqual("1") }) test("invalid form submission with unprocessable entity status", async ({ page }) => { await page.click("#reject form.unprocessable_entity input[type=submit]") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Unprocessable Entity", "renders the response HTML") - assert.notOk(await hasSelector(page, "#frame form.reject"), "replaces entire page") + await expect(page.locator("h1")).toHaveText("Unprocessable Entity") + await expect(page.locator("#frame form.reject")).not.toBeVisible() }) test("invalid form submission with long form", async ({ page }) => { await scrollToSelector(page, "#reject form.unprocessable_entity_with_tall_form input[type=submit]") await page.click("#reject form.unprocessable_entity_with_tall_form input[type=submit]") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Unprocessable Entity", "renders the response HTML") - assert(await isScrolledToTop(page), "page is scrolled to the top") - assert.notOk(await hasSelector(page, "#frame form.reject"), "replaces entire page") + await expect(page.locator("h1")).toHaveText("Unprocessable Entity") + expect(await isScrolledToTop(page)).toEqual(true) + await expect(page.locator("#frame form.reject")).not.toBeVisible() }) test("invalid form submission with server error status", async ({ page }) => { - assert(await hasSelector(page, "head > #form-fixture-styles")) + expect(await hasSelector(page, "head > #form-fixture-styles")).toEqual(true) await page.click("#reject form.internal_server_error input[type=submit]") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Internal Server Error", "renders the response HTML") - assert.notOk(await hasSelector(page, "head > #form-fixture-styles"), "replaces head") - assert.notOk(await hasSelector(page, "#frame form.reject"), "replaces entire page") + await expect(page.locator("h1")).toHaveText("Internal Server Error") + expect(await hasSelector(page, "head > #form-fixture-styles")).toEqual(false) + await expect(page.locator("#frame form.reject")).not.toBeVisible() }) test("form submission with network error", async ({ page }) => { @@ -565,10 +549,10 @@ test("form submission with network error", async ({ page }) => { test("submitter form submission reads button attributes", async ({ page }) => { const button = await page.locator("#submitter form button[type=submit][formmethod=post]") await button.click() - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/two.html") - assert.equal(await visitAction(page), "advance") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/two.html") + expect(await visitAction(page)).toEqual("advance") }) test("submitter POST form submission with multipart/form-data formenctype", async ({ page }) => { @@ -576,27 +560,21 @@ test("submitter POST form submission with multipart/form-data formenctype", asyn await nextBeat() const enctype = getSearchParam(page.url(), "enctype") - assert.ok(enctype?.startsWith("multipart/form-data"), "submits a multipart/form-data request") + expect(enctype).toContain("multipart/form-data") }) test("submitter GET submission from submitter with data-turbo-frame", async ({ page }) => { await page.click("#submitter form[method=get] [type=submit][data-turbo-frame]") - await nextBeat() - const message = await page.locator("#frame div.message") - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Form") - assert.equal(await message.textContent(), "Frame redirected") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#frame div.message")).toHaveText("Frame redirected") }) test("submitter POST submission from submitter with data-turbo-frame", async ({ page }) => { await page.click("#submitter form[method=post] [type=submit][data-turbo-frame]") - await nextBeat() - const message = await page.locator("#frame div.message") - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Form") - assert.equal(await message.textContent(), "Frame redirected") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#frame div.message")).toHaveText("Frame redirected") }) test("form[data-turbo-frame=_top] submission", async ({ page }) => { @@ -605,7 +583,7 @@ test("form[data-turbo-frame=_top] submission", async ({ page }) => { await form.locator("button").click() await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "One") + await expect(page.locator("h1")).toHaveText("One") }) test("form[data-turbo-frame=_top] submission within frame", async ({ page }) => { @@ -615,121 +593,111 @@ test("form[data-turbo-frame=_top] submission within frame", async ({ page }) => await form.locator("button").click() await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "Frames: Form") + await expect(page.locator("h1")).toHaveText("Frames: Form") }) test("frame form GET submission from submitter with data-turbo-frame=_top", async ({ page }) => { await page.click("#frame form[method=get] [type=submit][data-turbo-frame=_top]") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "One") + await expect(page.locator("h1")).toHaveText("One") }) test("frame form POST submission from submitter with data-turbo-frame=_top", async ({ page }) => { await page.click("#frame form[method=post] [type=submit][data-turbo-frame=_top]") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "One") + await expect(page.locator("h1")).toHaveText("One") }) test("frame POST form targeting frame submission", async ({ page }) => { await page.click("#targets-frame-post-form-submit") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) - assert.equal("frame", fetchOptions.headers["Turbo-Frame"]) + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") + expect(fetchOptions.headers["Turbo-Frame"]).toEqual("frame") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:frame-render") await nextEventNamed(page, "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) - const src = (await page.getAttribute("#frame", "src")) || "" - assert.equal(new URL(src).pathname, "/src/tests/fixtures/frames/frame.html") + const src = await page.getAttribute("#frame", "src") + expect(pathname(src)).toEqual("/src/tests/fixtures/frames/frame.html") }) test("frame POST form targeting frame toggles submitter's [disabled] attribute", async ({ page }) => { await page.click("#targets-frame-post-form-submit") - assert.equal( - await nextAttributeMutationNamed(page, "targets-frame-post-form-submit", "disabled"), - "", - "sets [disabled] on the submitter" + expect( + await nextAttributeMutationNamed(page, "targets-frame-post-form-submit", "disabled") + ).toEqual( + "" ) - assert.equal( - await nextAttributeMutationNamed(page, "targets-frame-post-form-submit", "disabled"), - null, - "removes [disabled] from the submitter" + expect( + await nextAttributeMutationNamed(page, "targets-frame-post-form-submit", "disabled") + ).toEqual( + null ) }) test("frame GET form targeting frame submission", async ({ page }) => { await page.click("#targets-frame-get-form-submit") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.notOk(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) - assert.equal("frame", fetchOptions.headers["Turbo-Frame"]) + expect(fetchOptions.headers["Accept"]).not.toContain("text/vnd.turbo-stream.html") + expect(fetchOptions.headers["Turbo-Frame"]).toEqual("frame") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:frame-render") await nextEventNamed(page, "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) - const src = (await page.getAttribute("#frame", "src")) || "" - assert.equal(new URL(src).pathname, "/src/tests/fixtures/frames/frame.html") + const src = await page.getAttribute("#frame", "src") + expect(pathname(src)).toEqual("/src/tests/fixtures/frames/frame.html") }) test("frame GET form targeting frame toggles submitter's [disabled] attribute", async ({ page }) => { await page.click("#targets-frame-get-form-submit") - assert.equal( - await nextAttributeMutationNamed(page, "targets-frame-get-form-submit", "disabled"), - "", - "sets [disabled] on the submitter" + expect( + await nextAttributeMutationNamed(page, "targets-frame-get-form-submit", "disabled") + ).toEqual( + "" ) - assert.equal( - await nextAttributeMutationNamed(page, "targets-frame-get-form-submit", "disabled"), - null, - "removes [disabled] from the submitter" + expect( + await nextAttributeMutationNamed(page, "targets-frame-get-form-submit", "disabled") + ).toEqual( + null ) }) test("frame form GET submission from submitter referencing another frame", async ({ page }) => { await page.click("#frame form[method=get] [type=submit][data-turbo-frame=hello]") - await nextBeat() - const title = await page.locator("h1") - const frameTitle = await page.locator("#hello h2") - assert.equal(await frameTitle.textContent(), "Hello from a frame") - assert.equal(await title.textContent(), "Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") + await expect(page.locator("h1")).toHaveText("Form") }) test("frame form POST submission from submitter referencing another frame", async ({ page }) => { await page.click("#frame form[method=post] [type=submit][data-turbo-frame=hello]") - await nextBeat() - const title = await page.locator("h1") - const frameTitle = await page.locator("#hello h2") - assert.equal(await frameTitle.textContent(), "Hello from a frame") - assert.equal(await title.textContent(), "Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") + await expect(page.locator("h1")).toHaveText("Form") }) test("frame form submission with redirect response", async ({ page }) => { @@ -737,67 +705,58 @@ test("frame form submission with redirect response", async ({ page }) => { const url = new URL(path, "http://localhost:9000") url.searchParams.set("enctype", "application/x-www-form-urlencoded;charset=UTF-8") - const button = await page.locator("#frame form.redirect input[type=submit]") - await button.click() + await page.click("#frame form.redirect input[type=submit]") await nextEventOnTarget(page, "frame", "turbo:frame-load") - const message = await page.locator("#frame div.message") - assert.notOk(await hasSelector(page, "#frame form.redirect")) - assert.equal(await message.textContent(), "Frame redirected") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html", "does not redirect _top") - assert.notOk(search(page.url()), "does not redirect _top") - assert.equal(await page.getAttribute("#frame", "src"), url.href, "redirects the target frame") + await expect(page.locator("#frame form.redirect")).not.toBeVisible() + await expect(page.locator("#frame div.message")).toHaveText("Frame redirected") + expect(pathname(page.url())).toContain("/src/tests/fixtures/form.html") + expect(search(page.url())).not.toBe() + await expect(page.locator("#frame")).toHaveAttribute("src", url.href) }) test("frame POST form submission toggles the ancestor frame's [aria-busy] attribute", async ({ page }) => { await page.click("#frame form.redirect input[type=submit]") - await nextBeat() - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), "", "sets [busy] on the #frame") - assert.equal(await nextAttributeMutationNamed(page, "frame", "aria-busy"), "true", "sets [aria-busy] on the #frame") - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), null, "removes [busy] from the #frame") - assert.equal( - await nextAttributeMutationNamed(page, "frame", "aria-busy"), - null, - "removes [aria-busy] from the #frame" + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual("") + expect(await nextAttributeMutationNamed(page, "frame", "aria-busy")).toEqual("true") + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual(null) + expect( + await nextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual( + null ) }) test("frame POST form submission toggles the target frame's [aria-busy] attribute", async ({ page }) => { await page.click('#targets-frame form.frame [type="submit"]') - await nextBeat() - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), "", "sets [busy] on the #frame") - assert.equal(await nextAttributeMutationNamed(page, "frame", "aria-busy"), "true", "sets [aria-busy] on the #frame") + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual("") + expect(await nextAttributeMutationNamed(page, "frame", "aria-busy")).toEqual("true") - const title = await page.locator("#frame h2") - assert.equal(await title.textContent(), "Frame: Loaded") - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), null, "removes [busy] from the #frame") - assert.equal( - await nextAttributeMutationNamed(page, "frame", "aria-busy"), - null, - "removes [aria-busy] from the #frame" + await expect(page.locator("#frame h2")).toHaveText("Frame: Loaded") + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual(null) + expect( + await nextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual( + null ) }) test("frame form submission with empty created response", async ({ page }) => { const htmlBefore = await outerHTMLForSelector(page, "#frame") - const button = await page.locator("#frame form.created input[type=submit]") - await button.click() - await nextBeat() + await page.click("#frame form.created input[type=submit]") const htmlAfter = await outerHTMLForSelector(page, "#frame") - assert.equal(htmlAfter, htmlBefore) + expect(htmlAfter).toEqual(htmlBefore) }) test("frame form submission with empty no-content response", async ({ page }) => { const htmlBefore = await outerHTMLForSelector(page, "#frame") - const button = await page.locator("#frame form.no-content input[type=submit]") - await button.click() - await nextBeat() + await page.click("#frame form.no-content input[type=submit]") const htmlAfter = await outerHTMLForSelector(page, "#frame") - assert.equal(htmlAfter, htmlBefore) + expect(htmlAfter).toEqual(htmlBefore) }) test("frame form submission within a frame submits the Turbo-Frame header", async ({ page }) => { @@ -805,136 +764,127 @@ test("frame form submission within a frame submits the Turbo-Frame header", asyn const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Turbo-Frame"], "submits with the Turbo-Frame header") + expect(fetchOptions.headers["Turbo-Frame"]).toEqual("frame") }) test("invalid frame form submission with unprocessable entity status", async ({ page }) => { await page.click("#frame form.unprocessable_entity input[type=submit]") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") await nextEventNamed(page, "turbo:before-fetch-request") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:frame-render") await nextEventNamed(page, "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) - const title = await page.locator("#frame h2") - assert.ok(await hasSelector(page, "#reject form"), "only replaces frame") - assert.equal(await title.textContent(), "Frame: Unprocessable Entity") + await expect(page.locator("#reject form:first-of-type")).toBeVisible() + await expect(page.locator("#frame h2")).toHaveText("Frame: Unprocessable Entity") }) test("invalid frame form submission with internal server error status", async ({ page }) => { await page.click("#frame form.internal_server_error input[type=submit]") - assert.ok(await formSubmitStarted(page), "fires turbo:submit-start") + expect(await formSubmitStarted(page)).toEqual("true") await nextEventNamed(page, "turbo:before-fetch-request") await nextEventNamed(page, "turbo:before-fetch-response") - assert.ok(await formSubmitEnded(page), "fires turbo:submit-end") + expect(await formSubmitEnded(page)).toEqual("true") await nextEventNamed(page, "turbo:frame-render") await nextEventNamed(page, "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) - assert.ok(await hasSelector(page, "#reject form"), "only replaces frame") - assert.equal(await page.textContent("#frame h2"), "Frame: Internal Server Error") + await expect(page.locator("#reject form:first-of-type")).toBeVisible() + await expect(page.locator("#frame h2")).toHaveText("Frame: Internal Server Error") }) test("frame form submission with stream response", async ({ page }) => { const button = await page.locator("#frame form.stream[method=post] input[type=submit]") await button.click() - await nextBeat() - const message = await page.locator("#frame div.message") - assert.ok(await hasSelector(page, "#frame form.redirect")) - assert.equal(await message.textContent(), "Hello!") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.notOk(await page.getAttribute("#frame", "src"), "does not change frame's src") + await expect(page.locator("#frame form.stream[method=post]")).toBeVisible() + await expect(page.locator("#frame div.message")).toHaveText("Hello!") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await page.getAttribute("#frame", "src")).not.toBe() }) test("frame form submission with HTTP verb other than GET or POST", async ({ page }) => { await page.click("#frame form.put.stream input[type=submit]") - await nextBeat() - assert.ok(await hasSelector(page, "#frame form.redirect")) - assert.equal(await page.textContent("#frame div.message"), "1: Hello!") - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") + await expect(page.locator("#frame form.put.stream")).toBeVisible() + await expect(page.locator("#frame div.message")).toHaveText("1: Hello!") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") }) test("frame form submission with [data-turbo=false] on the form", async ({ page }) => { await page.click('#frame form[data-turbo="false"] input[type=submit]') - await waitUntilSelector(page, "#element-id") - assert.notOk(await formSubmitStarted(page)) + await expect(page.locator("#element-id")).toBeVisible() + expect(await formSubmitStarted(page)).not.toBe() }) test("frame form submission with [data-turbo=false] on the submitter", async ({ page }) => { await page.click('#frame form:not([data-turbo]) input[data-turbo="false"]') - await waitUntilSelector(page, "#element-id") - assert.notOk(await formSubmitStarted(page)) + await expect(page.locator("#element-id")).toBeVisible() + expect(await formSubmitStarted(page)).not.toBe() }) test("frame form submission ignores submissions with their defaultPrevented", async ({ page }) => { await page.evaluate(() => document.addEventListener("submit", (event) => event.preventDefault(), true)) await page.click("#frame .redirect [type=submit]") - await nextBeat() - assert.equal(await page.textContent("#frame h2"), "Frame: Form") - assert.equal(await page.getAttribute("#frame", "src"), null, "does not navigate frame") + await expect(page.locator("#frame h2")).toHaveText("Frame: Form") + expect(await page.getAttribute("#frame", "src")).toEqual(null) }) test("form submission with [data-turbo=false] on the form", async ({ page }) => { await page.click('#turbo-false form[data-turbo="false"] input[type=submit]') - await waitUntilSelector(page, "#element-id") - assert.notOk(await formSubmitStarted(page)) + await expect(page.locator("#element-id")).toBeVisible() + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission with [data-turbo=false] on the submitter", async ({ page }) => { await page.click('#turbo-false form:not([data-turbo]) input[data-turbo="false"]') - await waitUntilSelector(page, "#element-id") - assert.notOk(await formSubmitStarted(page)) + await expect(page.locator("#element-id")).toBeVisible() + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission skipped within method=dialog", async ({ page }) => { await page.click('#dialog-method [type="submit"]') - await nextBeat() - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission skipped with submitter formmethod=dialog", async ({ page }) => { await page.click('#dialog-formmethod-turbo-frame [formmethod="dialog"]') - await nextBeat() - assert.notOk(await formSubmitEnded(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission targeting frame skipped within method=dialog", async ({ page }) => { await page.click("#dialog-method-turbo-frame button") - await nextBeat() - assert.notOk(await formSubmitEnded(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission targeting frame skipped with submitter formmethod=dialog", async ({ page }) => { await page.click('#dialog-formmethod [formmethod="dialog"]') - await nextBeat() - assert.notOk(await formSubmitStarted(page)) + expect(await formSubmitStarted(page)).not.toBe() }) test("form submission targets disabled frame", async ({ page }) => { await page.evaluate(() => document.getElementById("frame")?.setAttribute("disabled", "")) await page.click('#targets-frame form.one [type="submit"]') - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") }) test("form submission targeting a frame submits the Turbo-Frame header", async ({ page }) => { @@ -942,7 +892,7 @@ test("form submission targeting a frame submits the Turbo-Frame header", async ( const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Turbo-Frame"], "submits with the Turbo-Frame header") + expect(fetchOptions.headers["Turbo-Frame"]).toEqual("frame") }) test("link method form submission dispatches events from a connected element", async ({ page }) => { @@ -960,7 +910,7 @@ test("link method form submission dispatches events from a connected elem await nextEventOnTarget(page, "a-form-link", "turbo:before-fetch-response") await nextEventOnTarget(page, "a-form-link", "turbo:submit-end") - assert.notOk(await hasSelector(page, "a-form-link"), "the is removed") + await expect(page.locator("#a-form-link")).not.toBeVisible() }) test("link method form submission submits a single request", async ({ page }) => { @@ -968,13 +918,12 @@ test("link method form submission submits a single request", async ({ page }) => page.on("request", () => requestCounter++) await page.click("#stream-link-method-within-form-outside-frame") - await nextBeat() const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - assert.equal(fetchOptions.method, "post", "[data-turbo-method] overrides the GET method") - assert.equal(requestCounter, 1, "submits a single HTTP request") + await noNextEventNamed(page, "turbo:before-fetch-request") + expect(fetchOptions.method).toEqual("post") + expect(requestCounter).toEqual(1) }) test("link method form submission inside frame submits a single request", async ({ page }) => { @@ -982,13 +931,12 @@ test("link method form submission inside frame submits a single request", async page.on("request", () => requestCounter++) await page.click("#stream-link-method-inside-frame") - await nextBeat() const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - assert.equal(fetchOptions.method, "post", "[data-turbo-method] overrides the GET method") - assert.equal(requestCounter, 1, "submits a single HTTP request") + await noNextEventNamed(page, "turbo:before-fetch-request") + expect(fetchOptions.method).toEqual("post") + expect(requestCounter).toEqual(1) }) test("link method form submission targeting frame submits a single request", async ({ page }) => { @@ -996,47 +944,38 @@ test("link method form submission targeting frame submits a single request", asy page.on("request", () => requestCounter++) await page.click("#turbo-method-post-to-targeted-frame") - await nextBeat() const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - assert.equal(fetchOptions.method, "post", "[data-turbo-method] overrides the GET method") - assert.equal(requestCounter, 2, "submits a single HTTP request then follows a redirect") + await noNextEventNamed(page, "turbo:before-fetch-request") + expect(fetchOptions.method).toEqual("post") + expect(requestCounter).toEqual(2) }) test("link method form submission inside frame", async ({ page }) => { await page.click("#link-method-inside-frame") - await nextBeat() - assert.equal(await page.textContent("#frame h2"), "Frame: Loaded") - assert.notOk(await hasSelector(page, "#nested-child")) + await expect(page.locator("#frame h2")).toHaveText("Frame: Loaded") + await expect(page.locator("#nested-child")).not.toBeVisible() }) test("link method form submission inside frame with data-turbo-frame=_top", async ({ page }) => { await page.click("#link-method-inside-frame-target-top") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Hello") + await expect(page.locator("h1")).toHaveText("Hello") }) test("link method form submission inside frame with data-turbo-frame target", async ({ page }) => { await page.click("#link-method-inside-frame-with-target") - await nextBeat() - const title = await page.locator("h1") - const frameTitle = await page.locator("#hello h2") - assert.equal(await frameTitle.textContent(), "Hello from a frame") - assert.equal(await title.textContent(), "Form") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("stream link method form submission inside frame", async ({ page }) => { await page.click("#stream-link-method-inside-frame") - await nextBeat() - const message = page.locator("#frame div.message") - assert.equal(await message.textContent(), "Link!") + await expect(page.locator("#frame div.message")).toHaveText("Link!") }) test("stream link GET method form submission inside frame", async ({ page }) => { @@ -1044,7 +983,7 @@ test("stream link GET method form submission inside frame", async ({ page }) => const { fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") }) test("stream link inside frame", async ({ page }) => { @@ -1052,49 +991,42 @@ test("stream link inside frame", async ({ page }) => { const { fetchOptions, url } = await nextEventNamed(page, "turbo:before-fetch-request") - assert.ok(fetchOptions.headers["Accept"].includes("text/vnd.turbo-stream.html")) - assert.equal(getSearchParam(url, "content"), "Link!") + expect(fetchOptions.headers["Accept"]).toContain("text/vnd.turbo-stream.html") + expect(getSearchParam(url, "content")).toEqual("Link!") }) test("link method form submission within form inside frame", async ({ page }) => { await page.click("#stream-link-method-within-form-inside-frame") - await nextBeat() - const message = page.locator("#frame div.message") - assert.equal(await message.textContent(), "Link!") + await expect(page.locator("#frame div.message")).toHaveText("Link!") }) test("link method form submission inside frame with confirmation confirmed", async ({ page }) => { page.on("dialog", (dialog) => { - assert.equal(dialog.message(), "Are you sure?") + expect(dialog.message()).toEqual("Are you sure?") dialog.accept() }) await page.click("#link-method-inside-frame-with-confirmation") - await nextBeat() - const message = page.locator("#frame div.message") - assert.equal(await message.textContent(), "Link!") + await expect(page.locator("#frame div.message")).toHaveText("Link!") }) test("link method form submission inside frame with confirmation cancelled", async ({ page }) => { page.on("dialog", (dialog) => { - assert.equal(dialog.message(), "Are you sure?") + expect(dialog.message()).toEqual("Are you sure?") dialog.dismiss() }) await page.click("#link-method-inside-frame-with-confirmation") - await nextBeat() - assert.notOk(await hasSelector(page, "#frame div.message"), "Not confirming form submission does not submit the form") + await expect(page.locator("#frame div.message")).not.toBeVisible() }) test("link method form submission outside frame", async ({ page }) => { await page.click("#link-method-outside-frame") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Hello") + await expect(page.locator("h1")).toHaveText("Hello") }) test("following a link with [data-turbo-method] set and a target set navigates the target frame", async ({ @@ -1102,7 +1034,7 @@ test("following a link with [data-turbo-method] set and a target set navigates t }) => { await page.click("#turbo-method-post-to-targeted-frame") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame", "drives the turbo-frame") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("following a link with [data-turbo-method] and [data-turbo=true] set when html[data-turbo=false]", async ({ @@ -1116,22 +1048,22 @@ test("following a link with [data-turbo-method] and [data-turbo=true] set when h await link.click() - assert.equal(await page.textContent("h1"), "Form", "does not navigate the full page") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame", "drives the turbo-frame") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("following a link with [data-turbo-method] and [data-turbo=true] set when Turbo.session.drive = false", async ({ page }) => { - await page.evaluate(() => (window.Turbo.session.drive = false)) + await page.evaluate(() => window.Turbo.session.drive = false) const link = await page.locator("#turbo-method-post-to-targeted-frame") await link.evaluate((link) => link.setAttribute("data-turbo", "true")) await link.click() - assert.equal(await page.textContent("h1"), "Form", "does not navigate the full page") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame", "drives the turbo-frame") + await expect(page.locator("h1")).toHaveText("Form") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("following a link with [data-turbo-method] set when html[data-turbo=false]", async ({ page }) => { @@ -1140,93 +1072,79 @@ test("following a link with [data-turbo-method] set when html[data-turbo=false]" await page.click("#turbo-method-post-to-targeted-frame") - assert.equal(await page.textContent("h1"), "Hello", "treats link full-page navigation") + await expect(page.locator("h1")).toHaveText("Hello") }) test("following a link with [data-turbo-method] set when Turbo.session.drive = false", async ({ page }) => { await page.evaluate(() => (window.Turbo.session.drive = false)) await page.click("#turbo-method-post-to-targeted-frame") - assert.equal(await page.textContent("h1"), "Hello", "treats link full-page navigation") + await expect(page.locator("h1")).toHaveText("Hello") }) test("stream link method form submission outside frame", async ({ page }) => { await page.click("#stream-link-method-outside-frame") - await nextBeat() - const message = page.locator("#frame div.message") - assert.equal(await message.textContent(), "Link!") + await expect(page.locator("#frame div.message")).toHaveText("Link!") }) test("link method form submission within form outside frame", async ({ page }) => { await page.click("#link-method-within-form-outside-frame") - await nextBody(page) - const title = await page.locator("h1") - assert.equal(await title.textContent(), "Hello") + await expect(page.locator("h1")).toHaveText("Hello") }) test("stream link method form submission within form outside frame", async ({ page }) => { await page.click("#stream-link-method-within-form-outside-frame") - await nextBeat() - assert.equal(await page.textContent("#frame div.message"), "Link!") + await expect(page.locator("#frame div.message")).toHaveText("Link!") }) test("turbo:before-fetch-request fires on the form element", async ({ page }) => { await page.click('#targets-frame form.one [type="submit"]') - assert.ok(await nextEventOnTarget(page, "form_one", "turbo:before-fetch-request")) + await nextEventOnTarget(page, "form_one", "turbo:before-fetch-request") }) test("turbo:before-fetch-response fires on the form element", async ({ page }) => { await page.click('#targets-frame form.one [type="submit"]') - assert.ok(await nextEventOnTarget(page, "form_one", "turbo:before-fetch-response")) + await nextEventOnTarget(page, "form_one", "turbo:before-fetch-response") }) test("POST to external action ignored", async ({ page }) => { await page.click("#submit-external") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - - await nextBody(page) - - assert.equal(page.url(), "https://httpbin.org/post") + await noNextEventNamed(page, "turbo:before-fetch-request") + await expect(page).toHaveURL("https://httpbin.org/post") }) test("POST to external action within frame ignored", async ({ page }) => { await page.click("#submit-external-within-ignored") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - - await nextBody(page) - - assert.equal(page.url(), "https://httpbin.org/post") + await noNextEventNamed(page, "turbo:before-fetch-request") + await expect(page).toHaveURL("https://httpbin.org/post") }) test("POST to external action targeting frame ignored", async ({ page }) => { await page.click("#submit-external-target-ignored") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) - - await nextBody(page) - - assert.equal(page.url(), "https://httpbin.org/post") + await noNextEventNamed(page, "turbo:before-fetch-request") + await expect(page).toHaveURL("https://httpbin.org/post") }) test("form submission skipped with form[target]", async ({ page }) => { await page.click("#skipped form[target] button") await nextBeat() - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.notOk(await formSubmitEnded(page)) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await formSubmitEnded(page)).not.toBe() }) test("form submission skipped with submitter button[formtarget]", async ({ page }) => { await page.click("#skipped [formtarget]") await nextBeat() - assert.equal(pathname(page.url()), "/src/tests/fixtures/form.html") - assert.notOk(await formSubmitEnded(page)) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/form.html") + expect(await formSubmitEnded(page)).not.toBe() }) function formSubmitStarted(page) { diff --git a/src/tests/functional/frame_navigation_tests.js b/src/tests/functional/frame_navigation_tests.js index 77442d5a3..830958deb 100644 --- a/src/tests/functional/frame_navigation_tests.js +++ b/src/tests/functional/frame_navigation_tests.js @@ -1,6 +1,5 @@ -import { test } from "@playwright/test" +import { expect, test } from "@playwright/test" import { getFromLocalStorage, nextEventNamed, nextEventOnTarget, pathname, scrollToSelector } from "../helpers/page" -import { assert } from "chai" test("frame navigation with descendant link", async ({ page }) => { await page.goto("/src/tests/fixtures/frame_navigation.html") @@ -40,19 +39,19 @@ test("frame navigation emits fetch-request-error event when offline", async ({ p test("lazy-loaded frame promotes navigation", async ({ page }) => { await page.goto("/src/tests/fixtures/frame_navigation.html") - assert.equal(await page.textContent("#eager-loaded-frame h2"), "Eager-loaded frame: Not Loaded") + await expect(page.locator("#eager-loaded-frame h2")).toHaveText("Eager-loaded frame: Not Loaded") await scrollToSelector(page, "#eager-loaded-frame") await nextEventOnTarget(page, "eager-loaded-frame", "turbo:frame-load") - assert.equal(await page.textContent("#eager-loaded-frame h2"), "Eager-loaded frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame_for_eager.html") + await expect(page.locator("#eager-loaded-frame h2")).toHaveText("Eager-loaded frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame_for_eager.html") }) test("promoted frame navigation updates the URL before rendering", async ({ page }) => { await page.goto("/src/tests/fixtures/tabs.html") - page.evaluate(() => { + await page.evaluate(() => { addEventListener("turbo:before-frame-render", () => { localStorage.setItem("beforeRenderUrl", window.location.pathname) localStorage.setItem("beforeRenderContent", document.querySelector("#tab-content")?.textContent || "") @@ -62,13 +61,13 @@ test("promoted frame navigation updates the URL before rendering", async ({ page await page.click("#tab-2") await nextEventNamed(page, "turbo:before-frame-render") - assert.equal(await getFromLocalStorage(page, "beforeRenderUrl"), "/src/tests/fixtures/tabs/two.html") - assert.equal(await getFromLocalStorage(page, "beforeRenderContent"), "One") + expect(await getFromLocalStorage(page, "beforeRenderUrl")).toEqual("/src/tests/fixtures/tabs/two.html") + expect(await getFromLocalStorage(page, "beforeRenderContent")).toEqual("One") await nextEventNamed(page, "turbo:frame-render") - assert.equal(await pathname(page.url()), "/src/tests/fixtures/tabs/two.html") - assert.equal(await page.textContent("#tab-content"), "Two") + expect(await pathname(page.url())).toEqual("/src/tests/fixtures/tabs/two.html") + await expect(page.locator("#tab-content")).toHaveText("Two") }) test("promoted frame navigations are cached", async ({ page }) => { @@ -78,29 +77,29 @@ test("promoted frame navigations are cached", async ({ page }) => { await nextEventOnTarget(page, "tab-frame", "turbo:frame-load") await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("#tab-content"), "Two") - assert.equal(pathname((await page.getAttribute("#tab-frame", "src")) || ""), "/src/tests/fixtures/tabs/two.html") - assert.equal(await page.getAttribute("#tab-frame", "complete"), "", "sets [complete]") + await expect(page.locator("#tab-content")).toHaveText("Two") + expect(pathname(await page.getAttribute("#tab-frame", "src"))).toEqual("/src/tests/fixtures/tabs/two.html") + await expect(page.locator("#tab-frame")).toHaveAttribute("complete", "") await page.click("#tab-3") await nextEventOnTarget(page, "tab-frame", "turbo:frame-load") await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("#tab-content"), "Three") - assert.equal(pathname((await page.getAttribute("#tab-frame", "src")) || ""), "/src/tests/fixtures/tabs/three.html") - assert.equal(await page.getAttribute("#tab-frame", "complete"), "", "sets [complete]") + await expect(page.locator("#tab-content")).toHaveText("Three") + expect(pathname((await page.getAttribute("#tab-frame", "src")))).toEqual("/src/tests/fixtures/tabs/three.html") + await expect(page.locator("#tab-frame")).toHaveAttribute("complete", "") await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("#tab-content"), "Two") - assert.equal(pathname((await page.getAttribute("#tab-frame", "src")) || ""), "/src/tests/fixtures/tabs/two.html") - assert.equal(await page.getAttribute("#tab-frame", "complete"), "", "caches two.html with [complete]") + await expect(page.locator("#tab-content")).toHaveText("Two") + expect(pathname((await page.getAttribute("#tab-frame", "src")))).toEqual("/src/tests/fixtures/tabs/two.html") + await expect(page.locator("#tab-frame")).toHaveAttribute("complete", "") await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("#tab-content"), "One") - assert.equal(await page.getAttribute("#tab-frame", "src"), null, "caches one.html without #tab-frame[src]") - assert.equal(await page.getAttribute("#tab-frame", "complete"), null, "caches one.html without [complete]") + await expect(page.locator("#tab-content")).toHaveText("One") + await expect(page.locator("#tab-frame", "src")).not.toBe() + await expect(page.locator("#tab-frame", "complete")).not.toBe() }) diff --git a/src/tests/functional/frame_tests.js b/src/tests/functional/frame_tests.js index b090aff8a..dfdbd1935 100644 --- a/src/tests/functional/frame_tests.js +++ b/src/tests/functional/frame_tests.js @@ -1,8 +1,6 @@ -import { test, expect } from "@playwright/test" -import { assert, Assertion } from "chai" +import { expect, test } from "@playwright/test" import { attributeForSelector, - hasSelector, listenForEventOnTarget, nextAttributeMutationNamed, noNextAttributeMutationNamed, @@ -19,10 +17,6 @@ import { searchParams } from "../helpers/page" -assert.equalIgnoringWhitespace = function (actual, expected, message) { - new Assertion(actual?.trim()).to.equal(expected.trim(), message) -} - test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/frames.html") await readEventLogs(page) @@ -33,15 +27,13 @@ test("navigating a frame with Turbo.visit", async ({ page }) => { await page.locator("#frame").evaluate((frame) => frame.setAttribute("disabled", "")) await page.evaluate((pathname) => window.Turbo.visit(pathname, { frame: "frame" }), pathname) - await nextBeat() - assert.equal(await page.textContent("#frame h2"), "Frames: #frame", "does not navigate a disabled frame") + await expect(page.locator("#frame h2")).toHaveText("Frames: #frame") await page.locator("#frame").evaluate((frame) => frame.removeAttribute("disabled")) await page.evaluate((pathname) => window.Turbo.visit(pathname, { frame: "frame" }), pathname) - await nextBeat() - assert.equal(await page.textContent("#frame h2"), "Frame: Loaded", "navigates the target frame") + await expect(page.locator("#frame h2")).toHaveText("Frame: Loaded") }) test("navigating a frame a second time does not leak event listeners", async ({ page }) => { @@ -62,8 +54,8 @@ test("following a link preserves the current element's attributes" await nextBeat() const frame = await page.locator("turbo-frame#frame") - assert.equal(await frame.getAttribute("data-loaded-from"), currentPath) - assert.equal(await frame.getAttribute("src"), await propertyForSelector(page, "#hello a", "href")) + await expect(frame).toHaveAttribute("data-loaded-from", currentPath) + await expect(frame).toHaveAttribute("src", await propertyForSelector(page, "#hello a", "href")) }) test("following a link sets the frame element's [src]", async ({ page }) => { @@ -72,14 +64,14 @@ test("following a link sets the frame element's [src]", async ({ page }) => { const { url } = await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") const fetchRequestUrl = new URL(url) - assert.equal(fetchRequestUrl.pathname, "/src/tests/fixtures/frames/frame.html") - assert.equal(fetchRequestUrl.searchParams.get("key"), "value", "fetch request encodes query parameters") + expect(fetchRequestUrl.pathname).toEqual("/src/tests/fixtures/frames/frame.html") + expect(fetchRequestUrl.searchParams.get("key")).toEqual("value") await nextBeat() const src = new URL((await attributeForSelector(page, "#frame", "src")) || "") - assert.equal(src.pathname, "/src/tests/fixtures/frames/frame.html") - assert.equal(src.searchParams.get("key"), "value", "[src] attribute encodes query parameters") + expect(src.pathname).toEqual("/src/tests/fixtures/frames/frame.html") + expect(src.searchParams.get("key")).toEqual("value") }) test("following a link doesn't set the frame element's [src] if the link has [data-turbo-stream]", async ({ page }) => { @@ -92,7 +84,7 @@ test("following a link doesn't set the frame element's [src] if the link has [da const newSrc = await page.getAttribute("#frame", "src") - assert.equal(originalSrc, newSrc, "the turbo-frame src should not change after clicking the link") + expect(originalSrc).toEqual(newSrc) }) test("a frame whose src references itself does not infinitely loop", async ({ page }) => { @@ -102,23 +94,23 @@ test("a frame whose src references itself does not infinitely loop", async ({ pa await nextEventOnTarget(page, "frame", "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) }) test("following a link driving a frame toggles the [aria-busy=true] attribute", async ({ page }) => { await page.click("#hello a") - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), "", "sets [busy] on the #frame") - assert.equal( - await nextAttributeMutationNamed(page, "frame", "aria-busy"), - "true", - "sets [aria-busy=true] on the #frame" + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual("") + expect( + await nextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual( + "true" ) - assert.equal(await nextAttributeMutationNamed(page, "frame", "busy"), null, "removes [busy] on the #frame") - assert.equal( - await nextAttributeMutationNamed(page, "frame", "aria-busy"), - null, - "removes [aria-busy] from the #frame" + expect(await nextAttributeMutationNamed(page, "frame", "busy")).toEqual(null) + expect( + await nextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual( + null ) }) @@ -127,11 +119,10 @@ test("following an a[data-turbo-frame=_top] does not toggle the frame's [aria-bu }) => { await page.click("#frame #link-top") - assert.ok(await noNextAttributeMutationNamed(page, "frame", "busy"), "does not toggle [busy] on parent frame") - assert.ok( - await noNextAttributeMutationNamed(page, "frame", "aria-busy"), - "does not toggle [aria-busy=true] on parent frame" - ) + expect(await noNextAttributeMutationNamed(page, "frame", "busy")).toEqual(true) + expect( + await noNextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual(true) }) test("submitting a form[data-turbo-frame=_top] does not toggle the frame's [aria-busy=true] attribute", async ({ @@ -139,11 +130,10 @@ test("submitting a form[data-turbo-frame=_top] does not toggle the frame's [aria }) => { await page.click("#frame #form-submit-top") - assert.ok(await noNextAttributeMutationNamed(page, "frame", "busy"), "does not toggle [busy] on parent frame") - assert.ok( - await noNextAttributeMutationNamed(page, "frame", "aria-busy"), - "does not toggle [aria-busy=true] on parent frame" - ) + expect(await noNextAttributeMutationNamed(page, "frame", "busy")).toEqual(true) + expect( + await noNextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual(true) }) test("successfully following a link to a page without a matching frame dispatches a turbo:frame-missing event", async ({ @@ -152,21 +142,21 @@ test("successfully following a link to a page without a matching frame dispatche await page.click("#missing-frame-link") const { response } = await nextEventOnTarget(page, "missing", "turbo:frame-missing") - assert.equal(200, response.status) + expect(response.status).toEqual(200) }) test("successfully following a link to a page without a matching frame shows an error and throws an exception", async ({ page }) => { let error = undefined - page.once("pageerror", (e) => (error = e)) + page.once("pageerror", (e) => error = e) await page.click("#missing-frame-link") - assert.match(await page.innerText("#missing"), /Content missing/) + await expect(page.locator("#missing")).toHaveText("Content missing") - assert.exists(error) - assert.include(error.message, `The response (200) did not contain the expected `) + expect(error).not.toEqual(undefined) + expect(error.message).toContain(`The response (200) did not contain the expected `) }) test("successfully following a link to a page with `turbo-visit-control` `reload` performs a full page reload", async ({ @@ -175,7 +165,7 @@ test("successfully following a link to a page with `turbo-visit-control` `reload await page.click("#unvisitable-page-link") await page.getByText("Unvisitable page loaded").waitFor() - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/unvisitable.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/unvisitable.html") }) test("failing to follow a link to a page without a matching frame dispatches a turbo:frame-missing event", async ({ @@ -184,7 +174,7 @@ test("failing to follow a link to a page without a matching frame dispatches a t await page.click("#missing-page-link") const { response } = await nextEventOnTarget(page, "missing", "turbo:frame-missing") - assert.equal(404, response.status) + expect(response.status).toEqual(404) }) test("failing to follow a link to a page without a matching frame shows an error and throws an exception", async ({ @@ -195,10 +185,10 @@ test("failing to follow a link to a page without a matching frame shows an error await page.click("#missing-page-link") - assert.match(await page.innerText("#missing"), /Content missing/) + await expect(page.locator("#missing")).toHaveText("Content missing") - assert.exists(error) - assert.include(error.message, `The response (404) did not contain the expected `) + expect(error).not.toEqual(undefined) + expect(error.message).toContain(`The response (404) did not contain the expected `) }) test("the turbo:frame-missing event following a link to a page without a matching frame can be handled", async ({ @@ -219,7 +209,7 @@ test("the turbo:frame-missing event following a link to a page without a matchin await page.click("#missing-frame-link") await nextEventOnTarget(page, "missing", "turbo:frame-missing") - assert.equal(await page.textContent("#missing"), "Overridden") + await expect(page.locator("#missing")).toHaveText("Overridden") }) test("the turbo:frame-missing event following a link to a page without a matching frame can drive a Visit", async ({ @@ -241,14 +231,14 @@ test("the turbo:frame-missing event following a link to a page without a matchin await nextEventOnTarget(page, "missing", "turbo:frame-missing") await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "Frames: #frame") - assert.notOk(await hasSelector(page, "turbo-frame#missing")) + await expect(page.locator("h1")).toHaveText("Frames: #frame") + await expect(page.locator("turbo-frame#missing")).not.toBeVisible() await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames.html") - assert.ok(await hasSelector(page, "#missing-frame-link")) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames.html") + await expect(page.locator("#missing-frame-link")).toBeVisible() }) test("following a link to a page with a matching frame does not dispatch a turbo:frame-missing event", async ({ @@ -256,32 +246,27 @@ test("following a link to a page with a matching frame does not dispatch a turbo }) => { await page.click("#link-frame") - assert.ok(await noNextEventNamed(page, "turbo:frame-missing")) + expect(await noNextEventNamed(page, "turbo:frame-missing")).toEqual(true) await nextEventOnTarget(page, "frame", "turbo:frame-load") const src = await attributeForSelector(page, "#frame", "src") - assert( - src?.includes("/src/tests/fixtures/frames/frame.html"), - "navigates frame without dispatching turbo:frame-missing" - ) + expect(src).toContain("/src/tests/fixtures/frames/frame.html") }) test("following a link within a frame with a target set navigates the target frame", async ({ page }) => { await page.click("#hello a") - await nextBeat() - const frameText = await page.textContent("#frame h2") - assert.equal(frameText, "Frame: Loaded") + const frameText = await page.locator("#frame h2") + await expect(frameText).toHaveText("Frame: Loaded") }) test("following a link in rapid succession cancels the previous request", async ({ page }) => { await page.click("#outside-frame-form") await page.click("#outer-frame-link") - await nextBeat() - const frameText = await page.textContent("#frame h2") - assert.equal(frameText, "Frame: Loaded") + const frameText = await page.locator("#frame h2") + await expect(frameText).toHaveText("Frame: Loaded") }) test("following a link within a descendant frame whose ancestor declares a target set navigates the descendant frame", async ({ @@ -292,80 +277,74 @@ test("following a link within a descendant frame whose ancestor declares a targe const href = await propertyForSelector(page, selector, "href") await link.click() - await nextBeat() - const frame = await page.textContent("#frame h2") - const nestedRoot = await page.textContent("#nested-root h2") - const nestedChild = await page.textContent("#nested-child") - assert.equal(frame, "Frames: #frame") - assert.equal(nestedRoot, "Frames: #nested-root") - assert.equalIgnoringWhitespace(nestedChild, "Frame: Loaded") - assert.equal(await attributeForSelector(page, "#frame", "src"), null) - assert.equal(await attributeForSelector(page, "#nested-root", "src"), null) - assert.equal(await attributeForSelector(page, "#nested-child", "src"), href || "") + const frame = await page.locator("#frame h2") + const nestedRoot = await page.locator("#nested-root > h2") + const nestedChild = await page.locator("#nested-child > h2") + await expect(frame).toHaveText("Frames: #frame") + await expect(nestedRoot).toHaveText("Frames: #nested-root") + await expect(nestedChild).toHaveText("Frame: Loaded") + expect(await attributeForSelector(page, "#frame", "src")).toEqual(null) + expect(await attributeForSelector(page, "#nested-root", "src")).toEqual(null) + expect(await attributeForSelector(page, "#nested-child", "src")).toEqual(href) }) test("following a link that declares data-turbo-frame within a frame whose ancestor respects the override", async ({ page }) => { await page.click("#nested-root[target=frame] #nested-child a[data-turbo-frame]") - await nextBeat() - const frameText = await page.textContent("body > h1") - assert.equal(frameText, "One") - assert.notOk(await hasSelector(page, "#frame")) - assert.notOk(await hasSelector(page, "#nested-root")) - assert.notOk(await hasSelector(page, "#nested-child")) + const frameText = await page.locator("body > h1") + await expect(frameText).toHaveText("One") + await expect(page.locator("#frame")).not.toBeVisible() + await expect(page.locator("#nested-root")).not.toBeVisible() + await expect(page.locator("#nested-child")).not.toBeVisible() }) test("following a form within a nested frame with form target top", async ({ page }) => { await page.click("#nested-child-navigate-form-top-submit") - await nextBeat() - const frameText = await page.textContent("body > h1") - assert.equal(frameText, "One") - assert.notOk(await hasSelector(page, "#frame")) - assert.notOk(await hasSelector(page, "#nested-root")) - assert.notOk(await hasSelector(page, "#nested-child")) + const frameText = await page.locator("body > h1") + await expect(frameText).toHaveText("One") + await expect(page.locator("#frame")).not.toBeVisible() + await expect(page.locator("#nested-root")).not.toBeVisible() + await expect(page.locator("#nested-child")).not.toBeVisible() }) test("following a form within a nested frame with child frame target top", async ({ page }) => { await page.click("#nested-child-navigate-top-submit") - await nextBeat() - const frameText = await page.textContent("body > h1") - assert.equal(frameText, "One") - assert.notOk(await hasSelector(page, "#frame")) - assert.notOk(await hasSelector(page, "#nested-root")) - assert.notOk(await hasSelector(page, "#nested-child-navigate-top")) + const frameText = await page.locator("body > h1") + await expect(frameText).toHaveText("One") + await expect(page.locator("#frame")).not.toBeVisible() + await expect(page.locator("#nested-root")).not.toBeVisible() + await expect(page.locator("#nested-child")).not.toBeVisible() }) test("following a link within a frame with target=_top navigates the page", async ({ page }) => { - assert.equal(await attributeForSelector(page, "#navigate-top", "src"), null) + expect(await attributeForSelector(page, "#navigate-top", "src")).toEqual(null) await page.click("#navigate-top a:not([data-turbo-frame])") - await nextBeat() - const frameText = await page.textContent("body > h1") - assert.equal(frameText, "One") - assert.notOk(await hasSelector(page, "#navigate-top a")) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await searchParams(page.url()).get("key"), "value") + const frameText = await page.locator("body > h1") + await expect(frameText).toHaveText("One") + await expect(page.locator("#navigate-top a")).not.toBeVisible() + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await searchParams(page.url()).get("key")).toEqual("value") }) test("following a link that declares data-turbo-frame='_self' within a frame with target=_top navigates the frame itself", async ({ page }) => { - assert.equal(await attributeForSelector(page, "#navigate-top", "src"), null) + expect(await attributeForSelector(page, "#navigate-top", "src")).toEqual(null) await page.click("#navigate-top a[data-turbo-frame='_self']") - await nextBeat() - const title = await page.textContent("body > h1") - assert.equal(title, "Frames") - assert.ok(await hasSelector(page, "#navigate-top")) - const frame = await page.textContent("#navigate-top") - assert.equalIgnoringWhitespace(frame, "Replaced only the frame") + const title = await page.locator("body > h1") + await expect(title).toHaveText("Frames") + await expect(page.locator("#navigate-top")).toBeVisible() + const frame = await page.locator("#navigate-top") + await expect(frame).toHaveText("Replaced only the frame") }) test("following a link to a page with a which lazily loads a matching frame", async ({ @@ -373,13 +352,13 @@ test("following a link to a page with a which lazily loads }) => { await page.click("#recursive summary") - assert.ok(await hasSelector(page, "#recursive details[open]")) + await expect(page.locator("#recursive details[open]")).toBeVisible() await page.click("#recursive a") await nextEventOnTarget(page, "recursive", "turbo:frame-load") await nextEventOnTarget(page, "composer", "turbo:frame-load") - assert.ok(await hasSelector(page, "#recursive details:not([open])")) + await expect(page.locator("#recursive details:not([open])")).toBeVisible() }) test("submitting a form that redirects to a page with a which lazily loads a matching frame", async ({ @@ -387,62 +366,63 @@ test("submitting a form that redirects to a page with a wh }) => { await page.click("#recursive summary") - assert.ok(await hasSelector(page, "#recursive details[open]")) + await expect(page.locator("#recursive details[open]")).toBeVisible() await page.click("#recursive input[type=submit]") await nextEventOnTarget(page, "recursive", "turbo:frame-load") await nextEventOnTarget(page, "composer", "turbo:frame-load") - assert.ok(await hasSelector(page, "#recursive details:not([open])")) + await expect(page.locator("#recursive details:not([open])")).toBeVisible() }) test("removing [disabled] attribute from eager-loaded frame navigates it", async ({ page }) => { - await page.evaluate(() => document.getElementById("frame")?.setAttribute("disabled", "")) - await page.evaluate(() => - document.getElementById("frame")?.setAttribute("src", "/src/tests/fixtures/frames/frame.html") + const frame = await page.locator("#frame") + await frame.evaluate((frame) => frame.setAttribute("disabled", "")) + await frame.evaluate((frame) => + frame.setAttribute("src", "/src/tests/fixtures/frames/frame.html") ) - assert.ok( + expect( await noNextEventOnTarget(page, "frame", "turbo:before-fetch-request"), "[disabled] frames do not submit requests" - ) + ).toEqual(true) - await page.evaluate(() => document.getElementById("frame")?.removeAttribute("disabled")) + await frame.evaluate((frame) => frame.removeAttribute("disabled")) await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") }) test("evaluates frame script elements on each render", async ({ page }) => { - assert.equal(await frameScriptEvaluationCount(page), undefined) + expect(await frameScriptEvaluationCount(page)).toEqual(undefined) await page.click("#body-script-link") await nextEventOnTarget(page, "body-script", "turbo:frame-load") - assert.equal(await frameScriptEvaluationCount(page), 1) + expect(await frameScriptEvaluationCount(page)).toEqual(1) await page.click("#body-script-link") await nextEventOnTarget(page, "body-script", "turbo:frame-load") - assert.equal(await frameScriptEvaluationCount(page), 2) + expect(await frameScriptEvaluationCount(page)).toEqual(2) }) test("does not evaluate data-turbo-eval=false scripts", async ({ page }) => { await page.click("#eval-false-script-link") await nextBeat() - assert.equal(await frameScriptEvaluationCount(page), undefined) + expect(await frameScriptEvaluationCount(page)).toEqual(undefined) }) test("redirecting in a form is still navigatable after redirect", async ({ page }) => { await page.click("#navigate-form-redirect") await nextEventOnTarget(page, "form-redirect", "turbo:frame-load") - assert.equal(await page.textContent("turbo-frame#form-redirect h2"), "Form Redirect") + await expect(page.locator("turbo-frame#form-redirect h2")).toHaveText("Form Redirect") await page.click("#submit-form") await nextEventOnTarget(page, "form-redirect", "turbo:frame-load") - assert.equal(await page.textContent("turbo-frame#form-redirect h2"), "Form Redirected") + await expect(page.locator("turbo-frame#form-redirect h2")).toHaveText("Form Redirected") await page.click("#navigate-form-redirect") await nextEventOnTarget(page, "form-redirect", "turbo:frame-load") - assert.equal(await page.textContent("turbo-frame#form-redirect h2"), "Form Redirect") + await expect(page.locator("turbo-frame#form-redirect h2")).toHaveText("Form Redirect") }) test("'turbo:frame-render' is triggered after frame has finished rendering", async ({ page }) => { @@ -451,7 +431,7 @@ test("'turbo:frame-render' is triggered after frame has finished rendering", asy await nextEventNamed(page, "turbo:frame-render") // recursive const { fetchResponse } = await nextEventNamed(page, "turbo:frame-render") - assert.include(fetchResponse.response.url, "/src/tests/fixtures/frames/part.html") + expect(fetchResponse.response.url).toContain("/src/tests/fixtures/frames/part.html") }) test("navigating a frame from an outer form fires events", async ({ page }) => { @@ -460,12 +440,12 @@ test("navigating a frame from an outer form fires events", async ({ page }) => { await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") await nextEventOnTarget(page, "frame", "turbo:before-fetch-response") const { fetchResponse } = await nextEventOnTarget(page, "frame", "turbo:frame-render") - assert.include(fetchResponse.response.url, "/src/tests/fixtures/frames/form.html") + expect(fetchResponse.response.url).toContain("/src/tests/fixtures/frames/form.html") await nextEventOnTarget(page, "frame", "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) }) test("navigating a frame from an outer link fires events", async ({ page }) => { @@ -476,12 +456,12 @@ test("navigating a frame from an outer link fires events", async ({ page }) => { await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") await nextEventOnTarget(page, "frame", "turbo:before-fetch-response") const { fetchResponse } = await nextEventOnTarget(page, "frame", "turbo:frame-render") - assert.include(fetchResponse.response.url, "/src/tests/fixtures/frames/form.html") + expect(fetchResponse.response.url).toContain("/src/tests/fixtures/frames/form.html") await nextEventOnTarget(page, "frame", "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) }) test("navigating a frame from an inner link fires events", async ({ page }) => { @@ -492,12 +472,12 @@ test("navigating a frame from an inner link fires events", async ({ page }) => { await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") await nextEventOnTarget(page, "frame", "turbo:before-fetch-response") const { fetchResponse } = await nextEventOnTarget(page, "frame", "turbo:frame-render") - assert.include(fetchResponse.response.url, "/src/tests/fixtures/frames/frame.html") + expect(fetchResponse.response.url).toContain("/src/tests/fixtures/frames/frame.html") await nextEventOnTarget(page, "frame", "turbo:frame-load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) }) test("navigating a frame targeting _top from an outer link fires events", async ({ page }) => { @@ -512,7 +492,7 @@ test("navigating a frame targeting _top from an outer link fires events", async await nextEventOnTarget(page, "html", "turbo:load") const otherEvents = await readEventLogs(page) - assert.equal(otherEvents.length, 0, "no more events") + expect(otherEvents.length).toEqual(0) }) test("invoking .reload() re-fetches the frame's content", async ({ page }) => { @@ -522,8 +502,9 @@ test("invoking .reload() re-fetches the frame's content", async ({ page }) => { const dispatchedEvents = await readEventLogs(page) - assert.deepEqual( - dispatchedEvents.map(([name, _, id]) => [id, name]), + expect( + dispatchedEvents.map(([name, _, id]) => [id, name]) + ).toEqual( [ ["frame", "turbo:before-fetch-request"], ["frame", "turbo:before-fetch-response"], @@ -593,31 +574,31 @@ test("reconnecting after following a link does not reload the frame", async ({ p const eventLogs = await readEventLogs(page) const requestLogs = eventLogs.filter(([name]) => name == "turbo:before-fetch-request") - assert.equal(requestLogs.length, 0) + expect(requestLogs.length).toEqual(0) }) test("navigating pushing URL state from a frame navigation fires events", async ({ page }) => { await page.click("#link-outside-frame-action-advance") - assert.equal( - await nextAttributeMutationNamed(page, "frame", "aria-busy"), - "true", - "sets aria-busy on the " + expect( + await nextAttributeMutationNamed(page, "frame", "aria-busy") + ).toEqual( + "true" ) await nextEventOnTarget(page, "frame", "turbo:before-fetch-request") await nextEventOnTarget(page, "frame", "turbo:before-fetch-response") await nextEventOnTarget(page, "frame", "turbo:frame-render") await nextEventOnTarget(page, "frame", "turbo:frame-load") - assert.notOk(await nextAttributeMutationNamed(page, "frame", "aria-busy"), "removes aria-busy from the ") + expect(await nextAttributeMutationNamed(page, "frame", "aria-busy")).toEqual(null) - assert.equal(await nextAttributeMutationNamed(page, "html", "aria-busy"), "true", "sets aria-busy on the ") + expect(await nextAttributeMutationNamed(page, "html", "aria-busy")).toEqual("true") await nextEventOnTarget(page, "html", "turbo:before-visit") await nextEventOnTarget(page, "html", "turbo:visit") await nextEventOnTarget(page, "html", "turbo:before-cache") await nextEventOnTarget(page, "html", "turbo:before-render") await nextEventOnTarget(page, "html", "turbo:render") await nextEventOnTarget(page, "html", "turbo:load") - assert.notOk(await nextAttributeMutationNamed(page, "html", "aria-busy"), "removes aria-busy from the ") + expect(await nextAttributeMutationNamed(page, "html", "aria-busy")).toEqual(null) }) test("navigating a frame with a form[method=get] that does not redirect still updates the [src]", async ({ @@ -629,14 +610,14 @@ test("navigating a frame with a form[method=get] that does not redirect still up await nextEventOnTarget(page, "frame", "turbo:frame-render") await nextEventOnTarget(page, "frame", "turbo:frame-load") - assert.ok(await noNextEventNamed(page, "turbo:before-fetch-request")) + expect(await noNextEventNamed(page, "turbo:before-fetch-request")).toEqual(true) const src = (await attributeForSelector(page, "#frame", "src")) ?? "" - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(await page.textContent("h1"), "Frames") - assert.equal(await page.textContent("#frame h2"), "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames.html") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("h1")).toHaveText("Frames") + await expect(page.locator("#frame h2")).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames.html") }) test("navigating turbo-frame[data-turbo-action=advance] from within pushes URL state", async ({ page }) => { @@ -644,12 +625,12 @@ test("navigating turbo-frame[data-turbo-action=advance] from within pushes URL s await page.click("#link-frame") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") }) test("navigating turbo-frame[data-turbo-action=advance] to the same URL clears the [aria-busy] and [data-turbo-preview] state", async ({ @@ -662,9 +643,9 @@ test("navigating turbo-frame[data-turbo-action=advance] to the same URL clears t await page.click("#link-outside-frame-action-advance") await nextEventNamed(page, "turbo:load") - assert.equal(await attributeForSelector(page, "#frame", "aria-busy"), null, "clears turbo-frame[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "aria-busy"), null, "clears html[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "data-turbo-preview"), null, "clears html[aria-busy]") + expect(await attributeForSelector(page, "#frame", "aria-busy")).toEqual(null) + expect(await attributeForSelector(page, "#html", "aria-busy")).toEqual(null) + expect(await attributeForSelector(page, "#html", "data-turbo-preview")).toEqual(null) }) test("navigating a turbo-frame with an a[data-turbo-action=advance] preserves page state", async ({ page }) => { @@ -673,18 +654,18 @@ test("navigating a turbo-frame with an a[data-turbo-action=advance] preserves pa await page.click("#below-the-fold-link-frame-action") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.equal(await propertyForSelector(page, "#below-the-fold-input", "value"), "a value", "preserves page state") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#below-the-fold-input")).toHaveValue("a value") const { y } = await scrollPosition(page) - assert.notEqual(y, 0, "preserves Y scroll position") + expect(y).not.toEqual(0) }) test("a turbo-frame that has been driven by a[data-turbo-action] can be navigated normally", async ({ page }) => { @@ -692,61 +673,61 @@ test("a turbo-frame that has been driven by a[data-turbo-action] can be navigate await page.click("#link-hello-advance") await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("h1"), "Frames") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/hello.html") + await expect(page.locator("h1")).toHaveText("Frames") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/hello.html") await page.click("#hello a") await nextEventOnTarget(page, "hello", "turbo:frame-load") - assert.ok(await noNextEventNamed(page, "turbo:load")) - assert.equal(await page.textContent("#hello h2"), "Frames: #hello") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/hello.html") + expect(await noNextEventNamed(page, "turbo:load")).toEqual(true) + await expect(page.locator("#hello h2")).toHaveText("Frames: #hello") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/hello.html") }) test("navigating turbo-frame from within with a[data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#link-nested-frame-action-advance") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating frame with a[data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#link-outside-frame-action-advance") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating frame with form[method=get][data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#form-get-frame-action-advance button") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating frame with form[method=get][data-turbo-action=advance] to the same URL clears the [aria-busy] and [data-turbo-preview] state", async ({ @@ -759,24 +740,24 @@ test("navigating frame with form[method=get][data-turbo-action=advance] to the s await page.click("#form-get-frame-action-advance button") await nextEventNamed(page, "turbo:load") - assert.equal(await attributeForSelector(page, "#frame", "aria-busy"), null, "clears turbo-frame[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "aria-busy"), null, "clears html[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "data-turbo-preview"), null, "clears html[aria-busy]") + expect(await page.getAttribute("#frame", "aria-busy")).toEqual(null) + expect(await page.getAttribute("#html", "aria-busy")).toEqual(null) + expect(await page.getAttribute("#html", "data-turbo-preview")).toEqual(null) }) test("navigating frame with form[method=post][data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#form-post-frame-action-advance button") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating frame with form[method=post][data-turbo-action=advance] to the same URL clears the [aria-busy] and [data-turbo-preview] state", async ({ @@ -789,25 +770,25 @@ test("navigating frame with form[method=post][data-turbo-action=advance] to the await page.click("#form-post-frame-action-advance button") await nextEventNamed(page, "turbo:load") - assert.equal(await attributeForSelector(page, "#frame", "aria-busy"), null, "clears turbo-frame[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "aria-busy"), null, "clears html[aria-busy]") - assert.equal(await attributeForSelector(page, "#html", "data-turbo-preview"), null, "clears html[aria-busy]") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(await page.getAttribute("#frame", "aria-busy"), null) + expect(await page.getAttribute("#html", "aria-busy"), null) + expect(await page.getAttribute("#html", "data-turbo-preview"), null) + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating frame with button[data-turbo-action=advance] pushes URL state", async ({ page }) => { await page.click("#button-frame-action-advance") await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("navigating back after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames previous contents", async ({ @@ -819,14 +800,14 @@ test("navigating back after pushing URL state from a turbo-frame[data-turbo-acti await page.goBack() await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frames: #frame") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames.html") - assert.equal(await attributeForSelector(page, "#frame", "src"), null) - assert.equal(await propertyForSelector(page, "#frame", "src"), null) + await expect(title).toHaveText("Frames") + await expect(frameTitle).toHaveText("Frames: #frame") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames.html") + expect(await page.getAttribute("#frame", "src")).toEqual(null) + expect(await page.getAttribute("#frame", "src")).toEqual(null) }) test("navigating back then forward after pushing URL state from a turbo-frame[data-turbo-action=advance] restores the frames next contents", async ({ @@ -840,25 +821,25 @@ test("navigating back then forward after pushing URL state from a turbo-frame[da await page.goForward() await nextEventNamed(page, "turbo:load") - const title = await page.textContent("h1") - const frameTitle = await page.textContent("#frame h2") - const src = (await attributeForSelector(page, "#frame", "src")) ?? "" + const title = await page.locator("h1") + const frameTitle = await page.locator("#frame h2") + const src = await page.getAttribute("#frame", "src") - assert.ok(src.includes("/src/tests/fixtures/frames/frame.html"), "updates src attribute") - assert.equal(title, "Frames") - assert.equal(frameTitle, "Frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame.html") - assert.ok(await hasSelector(page, "#frame[complete]"), "marks the frame as [complete]") + expect(src).toContain("/src/tests/fixtures/frames/frame.html") + expect(title).toHaveText("Frames") + expect(frameTitle).toHaveText("Frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/frame.html") + await expect(page.locator("#frame[complete]")).toBeVisible() }) test("turbo:before-fetch-request fires on the frame element", async ({ page }) => { await page.click("#hello a") - assert.ok(await nextEventOnTarget(page, "frame", "turbo:before-fetch-request")) + expect(await nextEventOnTarget(page, "frame", "turbo:before-fetch-request")).not.toEqual(null) }) test("turbo:before-fetch-response fires on the frame element", async ({ page }) => { await page.click("#hello a") - assert.ok(await nextEventOnTarget(page, "frame", "turbo:before-fetch-response")) + expect(await nextEventOnTarget(page, "frame", "turbo:before-fetch-response")).not.toEqual(null) }) test("navigating a eager frame with a link[method=get] that does not fetch eager frame twice", async ({ @@ -873,13 +854,13 @@ test("navigating a eager frame with a link[method=get] that does not fetch eager ([name, options]) => name == "turbo:before-fetch-request" && options?.url?.includes("/src/tests/fixtures/frames/frame_for_eager.html") ) - assert.equal(fetchLogs.length, 1) + expect(fetchLogs.length).toEqual(1) - const src = (await attributeForSelector(page, "#eager-loaded-frame", "src")) ?? "" - assert.ok(src.includes("/src/tests/fixtures/frames/frame_for_eager.html"), "updates src attribute") - assert.equal(await page.textContent("h1"), "Eager-loaded frame") - assert.equal(await page.textContent("#eager-loaded-frame h2"), "Eager-loaded frame: Loaded") - assert.equal(pathname(page.url()), "/src/tests/fixtures/page_with_eager_frame.html") + const src = await page.getAttribute("#eager-loaded-frame", "src") + expect(src).toContain("/src/tests/fixtures/frames/frame_for_eager.html") + await expect(page.locator("h1")).toHaveText("Eager-loaded frame") + await expect(page.locator("#eager-loaded-frame h2")).toHaveText("Eager-loaded frame: Loaded") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/page_with_eager_frame.html") }) test("form submissions from frames clear snapshot cache", async ({ page }) => { @@ -940,7 +921,7 @@ async function withoutChangingEventListenersCount(page, callback) { await callback() const finalCount = await teardown() - assert.equal(finalCount, originalCount, "expected callback not to leak event listeners") + expect(finalCount).toEqual(originalCount) } function frameScriptEvaluationCount(page) { diff --git a/src/tests/functional/import_tests.js b/src/tests/functional/import_tests.js index d88dfe056..2d482b594 100644 --- a/src/tests/functional/import_tests.js +++ b/src/tests/functional/import_tests.js @@ -1,10 +1,6 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" test("window variable with ESM", async ({ page }) => { await page.goto("/src/tests/fixtures/esm.html") - const type = await page.evaluate(() => { - return typeof window.Turbo - }) - assert.equal(type, "object") + expect(await page.evaluate(() => typeof window.Turbo)).toEqual("object") }) diff --git a/src/tests/functional/loading_tests.js b/src/tests/functional/loading_tests.js index f9c28f361..bd27bbfcb 100644 --- a/src/tests/functional/loading_tests.js +++ b/src/tests/functional/loading_tests.js @@ -1,5 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { attributeForSelector, hasSelector, @@ -19,123 +18,110 @@ test.beforeEach(async ({ page }) => { test("eager loading within a details element", async ({ page }) => { await nextBeat() - assert.ok(await hasSelector(page, "#loading-eager turbo-frame#frame h2")) - assert.ok(await hasSelector(page, "#loading-eager turbo-frame[complete]"), "has [complete] attribute") + expect(await hasSelector(page, "#loading-eager turbo-frame#frame h2")).toEqual(true) + expect(await hasSelector(page, "#loading-eager turbo-frame[complete]")).toEqual(true) }) test("lazy loading within a details element", async ({ page }) => { - await nextBeat() - const frameContents = "#loading-lazy turbo-frame h2" - assert.notOk(await hasSelector(page, frameContents)) - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame:not([complete])")) + const contents = await page.locator(frameContents) + await expect(contents).not.toBeVisible() + expect(await hasSelector(page, "#loading-lazy turbo-frame:not([complete])")).toEqual(true) await page.click("#loading-lazy summary") - await nextBeat() - const contents = await page.locator(frameContents) - assert.equal(await contents.textContent(), "Hello from a frame") - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame[complete]"), "has [complete] attribute") + await expect(contents).toHaveText("Hello from a frame") + expect(await hasSelector(page, "#loading-lazy turbo-frame[complete]")).toEqual(true) }) test("changing loading attribute from lazy to eager loads frame", async ({ page }) => { - const frameContents = "#loading-lazy turbo-frame h2" - await nextBeat() + const frameContents = await page.locator("#loading-lazy turbo-frame h2") - assert.notOk(await hasSelector(page, frameContents)) + await expect(frameContents).not.toBeVisible() await page.evaluate(() => document.querySelector("#loading-lazy turbo-frame")?.setAttribute("loading", "eager")) - await nextBeat() - const contents = await page.locator(frameContents) await page.click("#loading-lazy summary") - assert.equal(await contents.textContent(), "Hello from a frame") + await expect(frameContents).toHaveText("Hello from a frame") }) test("navigating a visible frame with loading=lazy navigates", async ({ page }) => { await page.click("#loading-lazy summary") - await nextBeat() const initialContents = await page.locator("#hello h2") - assert.equal(await initialContents.textContent(), "Hello from a frame") + await expect(initialContents).toHaveText("Hello from a frame") await page.click("#hello a") - await nextBeat() const navigatedContents = await page.locator("#hello h2") - assert.equal(await navigatedContents.textContent(), "Frames: #hello") + await expect(navigatedContents).toHaveText("Frames: #hello") }) test("changing src attribute on a frame with loading=lazy defers navigation", async ({ page }) => { - const frameContents = "#loading-lazy turbo-frame h2" - await nextBeat() + const frameContents = await page.locator("#loading-lazy turbo-frame h2") await page.evaluate(() => document.querySelector("#loading-lazy turbo-frame")?.setAttribute("src", "/src/tests/fixtures/frames.html") ) - assert.notOk(await hasSelector(page, frameContents)) + await expect(frameContents).not.toBeVisible() await page.click("#loading-lazy summary") - await nextBeat() - const contents = await page.locator(frameContents) - assert.equal(await contents.textContent(), "Frames: #hello") + await expect(frameContents).toHaveText("Frames: #hello") }) test("changing src attribute on a frame with loading=eager navigates", async ({ page }) => { - const frameContents = "#loading-eager turbo-frame h2" - await nextBeat() + const frame = await page.locator("#loading-eager turbo-frame") + const frameContents = await frame.locator("h2") - await page.evaluate(() => - document.querySelector("#loading-eager turbo-frame")?.setAttribute("src", "/src/tests/fixtures/frames.html") + await frame.evaluate((frame) => + frame.setAttribute("src", "/src/tests/fixtures/frames.html") ) await page.click("#loading-eager summary") - await nextBeat() - const contents = await page.locator(frameContents) - assert.equal(await contents.textContent(), "Frames: #frame") + await expect(frameContents).toHaveText("Frames: #frame") }) test("reloading a frame reloads the content", async ({ page }) => { + const frame = await page.locator("#loading-eager turbo-frame#frame") await page.click("#loading-eager summary") await nextEventOnTarget(page, "frame", "turbo:frame-load") - const frameContent = "#loading-eager turbo-frame#frame h2" - assert.ok(await hasSelector(page, frameContent)) - assert.equal(await nextAttributeMutationNamed(page, "frame", "complete"), "", "has [complete] attribute") + const frameContent = await frame.locator("h2") + await expect(frameContent).toBeVisible() + expect(await nextAttributeMutationNamed(page, "frame", "complete")).toEqual("") - await page.evaluate(() => document.querySelector("#loading-eager turbo-frame")?.reload()) - assert.ok(await hasSelector(page, frameContent)) - assert.equal(await nextAttributeMutationNamed(page, "frame", "complete"), null, "clears [complete] attribute") + await frame.evaluate(() => frame.reload()) + await expect(frameContent).toBeVisible() + expect(await nextAttributeMutationNamed(page, "frame", "complete")).toEqual(null) }) test("navigating away from a page does not reload its frames", async ({ page }) => { await page.click("#one") - await nextBody(page) const eventLogs = await readEventLogs(page) const requestLogs = eventLogs.filter(([name]) => name == "turbo:before-fetch-request") - assert.equal(requestLogs.length, 1) + expect(requestLogs.length).toEqual(1) }) test("removing the [complete] attribute of an eager frame reloads the content", async ({ page }) => { + const frame = await page.locator("#loading-eager turbo-frame") await nextEventOnTarget(page, "frame", "turbo:frame-load") - await page.evaluate(() => document.querySelector("#loading-eager turbo-frame")?.removeAttribute("complete")) + await frame.evaluate((frame) => frame.removeAttribute("complete")) await nextEventOnTarget(page, "frame", "turbo:frame-load") - assert.ok( - await hasSelector(page, "#loading-eager turbo-frame[complete]"), - "sets the [complete] attribute after re-loading" - ) + expect( + await hasSelector(page, "#loading-eager turbo-frame[complete]") + ).toEqual(true) }) test("changing [src] attribute on a [complete] frame with loading=lazy defers navigation", async ({ page }) => { await page.click("#loading-lazy summary") await nextEventOnTarget(page, "hello", "turbo:frame-load") - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame[complete]"), "lazy frame is complete") - assert.equal(await page.textContent("#hello h2"), "Hello from a frame") + expect(await hasSelector(page, "#loading-lazy turbo-frame[complete]")).toEqual(true) + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") await page.click("#loading-lazy summary") await page.click("#one") @@ -143,26 +129,26 @@ test("changing [src] attribute on a [complete] frame with loading=lazy defers na await page.goBack() await nextEventNamed(page, "turbo:load") - assert.ok(await noNextEventOnTarget(page, "hello", "turbo:frame-load")) + expect(await noNextEventOnTarget(page, "hello", "turbo:frame-load")).toEqual(true) let src = new URL((await attributeForSelector(page, "#hello", "src")) || "") - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame[complete]"), "lazy frame is complete") - assert.equal(src.pathname, "/src/tests/fixtures/frames/hello.html", "lazy frame retains [src]") + expect(await hasSelector(page, "#loading-lazy turbo-frame[complete]")).toEqual(true) + expect(src.pathname).toEqual("/src/tests/fixtures/frames/hello.html") await page.click("#link-lazy-frame") - assert.ok(await noNextEventOnTarget(page, "hello", "turbo:frame-load")) - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame:not([complete])"), "lazy frame is not complete") + expect(await noNextEventOnTarget(page, "hello", "turbo:frame-load")).toEqual(true) + expect(await hasSelector(page, "#loading-lazy turbo-frame:not([complete])")).toEqual(true) await page.click("#loading-lazy summary") await nextEventOnTarget(page, "hello", "turbo:frame-load") src = new URL((await attributeForSelector(page, "#hello", "src")) || "") - assert.equal(await page.textContent("#loading-lazy turbo-frame h2"), "Frames: #hello") - assert.ok(await hasSelector(page, "#loading-lazy turbo-frame[complete]"), "lazy frame is complete") - assert.equal(src.pathname, "/src/tests/fixtures/frames.html", "lazy frame navigates") + await expect(page.locator("#loading-lazy turbo-frame h2")).toHaveText("Frames: #hello") + expect(await hasSelector(page, "#loading-lazy turbo-frame[complete]")).toEqual(true) + expect(src.pathname).toEqual("/src/tests/fixtures/frames.html") }) test("navigating away from a page and then back does not reload its frames", async ({ page }) => { @@ -177,8 +163,8 @@ test("navigating away from a page and then back does not reload its frames", asy const requestsOnEagerFrame = requestLogs.filter((record) => record[2] == "frame") const requestsOnLazyFrame = requestLogs.filter((record) => record[2] == "hello") - assert.equal(requestsOnEagerFrame.length, 0, "does not reload eager frame") - assert.equal(requestsOnLazyFrame.length, 0, "does not reload lazy frame") + expect(requestsOnEagerFrame.length).toEqual(0) + expect(requestsOnLazyFrame.length).toEqual(0) await page.click("#loading-lazy summary") await nextEventOnTarget(page, "hello", "turbo:before-fetch-request") @@ -204,5 +190,5 @@ test("disconnecting and reconnecting a frame does not reload the frame", async ( const eventLogs = await readEventLogs(page) const requestLogs = eventLogs.filter(([name]) => name == "turbo:before-fetch-request") - assert.equal(requestLogs.length, 0) + expect(requestLogs.length).toEqual(0) }) diff --git a/src/tests/functional/navigation_tests.js b/src/tests/functional/navigation_tests.js index 73871e1c2..0fbc8e05b 100644 --- a/src/tests/functional/navigation_tests.js +++ b/src/tests/functional/navigation_tests.js @@ -1,10 +1,8 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { clickWithoutScrolling, getSearchParam, hash, - hasSelector, isScrolledToSelector, nextAttributeMutationNamed, nextBeat, @@ -17,8 +15,6 @@ import { search, selectorHasFocus, visitAction, - waitUntilSelector, - waitUntilNoSelector, willChangeBody } from "../helpers/page" @@ -31,23 +27,20 @@ test("navigating renders a progress bar until the next turbo:load", async ({ pag await page.evaluate(() => window.Turbo.setProgressBarDelay(0)) await page.click("#delayed-link") - await waitUntilSelector(page, ".turbo-progress-bar") - assert.ok(await hasSelector(page, ".turbo-progress-bar"), "displays progress bar") + await expect(page.locator(".turbo-progress-bar")).toBeVisible() await nextEventNamed(page, "turbo:render") assert.ok(await hasSelector(page, ".turbo-progress-bar"), "displays progress bar") await nextEventNamed(page, "turbo:load") - await waitUntilNoSelector(page, ".turbo-progress-bar") - - assert.notOk(await hasSelector(page, ".turbo-progress-bar"), "hides progress bar") + await expect(page.locator(".turbo-progress-bar")).not.toBeVisible() }) test("navigating does not render a progress bar before expiring the delay", async ({ page }) => { await page.evaluate(() => window.Turbo.setProgressBarDelay(1000)) await page.click("#same-origin-unannotated-link") - assert.notOk(await hasSelector(page, ".turbo-progress-bar"), "does not show progress bar before delay") + await expect(page.locator(".turbo-progress-bar")).not.toBeVisible() }) test("navigating hides the progress bar on failure", async ({ page }) => { @@ -59,24 +52,24 @@ test("navigating hides the progress bar on failure", async ({ page }) => { }) test("after loading the page", async ({ page }) => { - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await visitAction(page), "load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin unannotated link", async ({ page }) => { await page.click("#same-origin-unannotated-link") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - "true", - "sets [aria-busy] on the document element" + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + "true" ) - assert.equal( - await nextAttributeMutationNamed(page, "html", "aria-busy"), - null, - "removes [aria-busy] from the document element" + expect( + await nextAttributeMutationNamed(page, "html", "aria-busy") + ).toEqual( + null ) }) @@ -87,60 +80,60 @@ test("following a same-origin unannotated custom element link", async ({ page }) const link = shadowRoot?.querySelector("a") link?.click() }) - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(search(page.url()), "") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(search(page.url())).toEqual("") + expect(await visitAction(page)).toEqual("advance") }) test("drive enabled; click an element in the shadow DOM wrapped by a link in the light DOM", async ({ page }) => { await page.click("#shadow-dom-drive-enabled span") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") }) test("drive disabled; click an element in the shadow DOM within data-turbo='false'", async ({ page }) => { await page.click("#shadow-dom-drive-disabled span") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "load") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("load") }) test("drive enabled; click an element in the slot", async ({ page }) => { await page.click("#element-in-slot") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") }) test("drive disabled; click an element in the slot within data-turbo='false'", async ({ page }) => { await page.click("#element-in-slot-disabled") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "load") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("load") }) test("drive disabled; click an element in the nested slot within data-turbo='false'", async ({ page }) => { await page.click("#element-in-nested-slot-disabled") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "load") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin unannotated link with search params", async ({ page }) => { await page.click("#same-origin-unannotated-link-search-params") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(search(page.url()), "?key=value") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(search(page.url())).toEqual("?key=value") + expect(await visitAction(page)).toEqual("advance") }) test("following a same-origin unannotated form[method=GET]", async ({ page }) => { await page.click("#same-origin-unannotated-form button") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") }) test("following a same-origin data-turbo-method=get link", async ({ page }) => { @@ -149,46 +142,46 @@ test("following a same-origin data-turbo-method=get link", async ({ page }) => { await nextEventNamed(page, "turbo:submit-end") await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(getSearchParam(page.url(), "a"), "one") - assert.equal(getSearchParam(page.url(), "b"), "two") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(getSearchParam(page.url(), "a")).toEqual("one") + expect(getSearchParam(page.url(), "b")).toEqual("two") }) test("following a same-origin data-turbo-action=replace link", async ({ page }) => { await page.click("#same-origin-replace-link") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a same-origin GET form[data-turbo-action=replace]", async ({ page }) => { await page.click("#same-origin-replace-form-get button") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a same-origin GET form button[data-turbo-action=replace]", async ({ page }) => { await page.click("#same-origin-replace-form-submitter-get button") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a same-origin POST form[data-turbo-action=replace]", async ({ page }) => { await page.click("#same-origin-replace-form-post button") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a same-origin POST form button[data-turbo-action=replace]", async ({ page }) => { await page.click("#same-origin-replace-form-submitter-post button") await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a POST form clears cache", async ({ page }) => { @@ -200,131 +193,136 @@ test("following a POST form clears cache", async ({ page }) => { await page.click("#form-post-submit") await nextBeat() // 301 redirect response await nextBeat() // 200 response + + await expect(page.locator("h1")).toHaveText("One") + await page.goBack() - assert.notOk(await hasSelector(page, "some-cached-element")) + + await expect(page.locator("h1")).toHaveText("Navigation") + await expect(page.locator("some-cached-element")).not.toBeVisible() }) test("following a same-origin POST link with data-turbo-action=replace", async ({ page }) => { await page.click("#same-origin-replace-post-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("following a same-origin data-turbo=false link", async ({ page }) => { await page.click("#same-origin-false-link") await page.waitForEvent("load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin unannotated link inside a data-turbo=false container", async ({ page }) => { await page.click("#same-origin-unannotated-link-inside-false-container") await page.waitForEvent("load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin data-turbo=true link inside a data-turbo=false container", async ({ page }) => { await page.click("#same-origin-true-link-inside-false-container") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") }) test("following a same-origin anchored link", async ({ page }) => { await page.click("#same-origin-anchored-link") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(hash(page.url()), "#element-id") - assert.equal(await visitAction(page), "advance") - assert(await isScrolledToSelector(page, "#element-id")) + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(hash(page.url())).toEqual("#element-id") + expect(await visitAction(page)).toEqual("advance") + expect(await isScrolledToSelector(page, "#element-id")).toEqual(true) }) test("following a same-origin link to a named anchor", async ({ page }) => { await page.click("#same-origin-anchored-link-named") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(hash(page.url()), "#named-anchor") - assert.equal(await visitAction(page), "advance") - assert(await isScrolledToSelector(page, "[name=named-anchor]")) + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(hash(page.url())).toEqual("#named-anchor") + expect(await visitAction(page)).toEqual("advance") + expect(await isScrolledToSelector(page, "[name=named-anchor]")).toEqual(true) }) test("following a cross-origin unannotated link", async ({ page }) => { await page.click("#cross-origin-unannotated-link") - await nextBody(page) - assert.equal(page.url(), "about:blank") - assert.equal(await visitAction(page), "load") + + expect(page.url()).toEqual("about:blank") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin [target] link", async ({ page }) => { const [popup] = await Promise.all([page.waitForEvent("popup"), page.click("#same-origin-targeted-link")]) - assert.equal(pathname(popup.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(popup), "load") + expect(pathname(popup.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(popup)).toEqual("load") }) test("following a same-origin [download] link", async ({ page }) => { - assert.notOk( + expect( await willChangeBody(page, async () => { await page.click("#same-origin-download-link") await nextBeat() }) - ) - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await visitAction(page), "load") + ).toEqual(false) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await visitAction(page)).toEqual("load") }) test("following a same-origin link inside an SVG element", async ({ page }) => { await page.click("#same-origin-link-inside-svg-element", { force: true }) - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "advance") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("advance") }) test("following a cross-origin link inside an SVG element", async ({ page }) => { await page.click("#cross-origin-link-inside-svg-element", { force: true }) - await nextBody(page) - assert.equal(page.url(), "about:blank") - assert.equal(await visitAction(page), "load") + + expect(page.url()).toEqual("about:blank") + expect(await visitAction(page)).toEqual("load") }) test("clicking the back button", async ({ page }) => { await page.click("#same-origin-unannotated-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await page.goBack() - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await visitAction(page), "restore") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await visitAction(page)).toEqual("restore") }) test("clicking the forward button", async ({ page }) => { await page.click("#same-origin-unannotated-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await page.goBack() await page.goForward() - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "restore") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("restore") }) test("link targeting a disabled turbo-frame navigates the page", async ({ page }) => { await page.click("#link-to-disabled-frame") - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/hello.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/frames/hello.html") }) test("skip link with hash-only path scrolls to the anchor without a visit", async ({ page }) => { - assert.notOk( + expect( await willChangeBody(page, async () => { await page.click('a[href="#main"]') await nextBeat() }) - ) + ).toEqual(false) - assert.ok(await isScrolledToSelector(page, "#main"), "scrolled to #main") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(hash(page.url()), "#main") + expect(await isScrolledToSelector(page, "#main")).toEqual(true) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(hash(page.url())).toEqual("#main") }) test("skip link with hash-only path moves focus and changes tab order", async ({ page }) => { @@ -332,18 +330,18 @@ test("skip link with hash-only path moves focus and changes tab order", async ({ await nextBeat() await page.press("#main", "Tab") - assert.notOk(await selectorHasFocus(page, "#ignored-link"), "skips interactive elements before #main") - assert.ok(await selectorHasFocus(page, "#main *:focus"), "moves focus inside #main") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(hash(page.url()), "#main") + await expect(page.locator("#ignored-link")).not.toBeFocused() + expect(await selectorHasFocus(page, "#main *:focus")).toEqual(true) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(hash(page.url())).toEqual("#main") }) test("same-page anchored replace link assumes the intention was a refresh", async ({ page }) => { await page.click("#refresh-link") - await nextBody(page) - assert.ok(await isScrolledToSelector(page, "#main"), "scrolled to #main") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(hash(page.url()), "#main") + await nextEventNamed(page, "turbo:load") + expect(await isScrolledToSelector(page, "#main"), "scrolled to #main").toEqual(true) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(hash(page.url())).toEqual("#main") }) test("navigating back to anchored URL", async ({ page }) => { @@ -351,30 +349,30 @@ test("navigating back to anchored URL", async ({ page }) => { await nextBeat() await clickWithoutScrolling(page, "#same-origin-unannotated-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await nextBeat() await page.goBack() - await nextBody(page) + await nextEventNamed(page, "turbo:load") - assert.ok(await isScrolledToSelector(page, "#main"), "scrolled to #main") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(hash(page.url()), "#main") + expect(await isScrolledToSelector(page, "#main")).toEqual(true) + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(hash(page.url())).toEqual("#main") }) test("following a redirection", async ({ page }) => { await page.click("#redirection-link") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") - assert.equal(await visitAction(page), "replace") + await nextEventNamed(page, "turbo:load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") + expect(await visitAction(page)).toEqual("replace") }) test("clicking the back button after redirection", async ({ page }) => { await page.click("#redirection-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") await page.goBack() - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await visitAction(page), "restore") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await visitAction(page)).toEqual("restore") }) test("same-page anchor visits do not trigger visit events", async ({ page }) => { @@ -390,38 +388,37 @@ test("same-page anchor visits do not trigger visit events", async ({ page }) => for (const eventName in events) { await page.goto("/src/tests/fixtures/navigation.html") await page.click('a[href="#main"]') - assert.ok(await noNextEventNamed(page, eventName), `same-page links do not trigger ${eventName} events`) + expect(await noNextEventNamed(page, eventName)).toEqual(true) } }) test("correct referrer header", async ({ page }) => { - page.click("#headers-link") - await nextBody(page) + await page.click("#headers-link") + await nextEventNamed(page, "turbo:load") const pre = await page.textContent("pre") const headers = await JSON.parse(pre || "") - assert.equal( - headers.referer, - "http://localhost:9000/src/tests/fixtures/navigation.html", - `referer header is correctly set` + expect( + headers.referer + ).toEqual( + "http://localhost:9000/src/tests/fixtures/navigation.html" ) }) test("double-clicking on a link", async ({ page }) => { await page.click("#delayed-link", { clickCount: 2 }) - await nextBeat() await nextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/__turbo/delayed_response") - assert.equal(await visitAction(page), "advance") + expect(pathname(page.url())).toEqual("/__turbo/delayed_response") + expect(await visitAction(page)).toEqual("advance") }) test("does not fire turbo:load twice after following a redirect", async ({ page }) => { - page.click("#redirection-link") + await page.click("#redirection-link") await nextBeat() // 301 redirect response - assert.ok(await noNextEventNamed(page, "turbo:load")) + expect(await noNextEventNamed(page, "turbo:load")).toEqual(true) await nextBeat() // 200 response await nextBody(page) @@ -429,18 +426,15 @@ test("does not fire turbo:load twice after following a redirect", async ({ page }) test("navigating back whilst a visit is in-flight", async ({ page }) => { - page.click("#delayed-link") + await page.click("#delayed-link") await nextEventNamed(page, "turbo:before-render") await page.goBack() - assert.ok( - await nextEventNamed(page, "turbo:visit"), - "navigating back whilst a visit is in-flight starts a non-silent Visit" - ) + await nextEventNamed(page, "turbo:visit") + await nextEventNamed(page, "turbo:load") - await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await visitAction(page), "restore") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await visitAction(page)).toEqual("restore") }) test("ignores links with a [target] attribute that target an iframe with a matching [name]", async ({ page }) => { @@ -448,8 +442,8 @@ test("ignores links with a [target] attribute that target an iframe with a match await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await pathnameForIFrame(page, "iframe"), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await pathnameForIFrame(page, "iframe")).toEqual("/src/tests/fixtures/one.html") }) test("ignores links with a [target] attribute that targets an iframe with [name='']", async ({ page }) => { @@ -457,7 +451,7 @@ test("ignores links with a [target] attribute that targets an iframe with [name= await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") }) test("ignores forms with a [target] attribute that targets an iframe with a matching [name]", async ({ page }) => { @@ -465,8 +459,8 @@ test("ignores forms with a [target] attribute that targets an iframe with a matc await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await pathnameForIFrame(page, "iframe"), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await pathnameForIFrame(page, "iframe")).toEqual("/src/tests/fixtures/one.html") }) test("ignores forms with a button[formtarget] attribute that targets an iframe with [name='']", async ({ @@ -476,7 +470,7 @@ test("ignores forms with a button[formtarget] attribute that targets an iframe w await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") }) test("ignores forms with a button[formtarget] attribute that targets an iframe with a matching [name]", async ({ @@ -486,8 +480,8 @@ test("ignores forms with a button[formtarget] attribute that targets an iframe w await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/navigation.html") - assert.equal(await pathnameForIFrame(page, "iframe"), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/navigation.html") + expect(await pathnameForIFrame(page, "iframe")).toEqual("/src/tests/fixtures/one.html") }) test("ignores forms with a [target] attribute that target an iframe with [name='']", async ({ page }) => { @@ -495,5 +489,5 @@ test("ignores forms with a [target] attribute that target an iframe with [name=' await nextBeat() await noNextEventNamed(page, "turbo:load") - assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/one.html") }) diff --git a/src/tests/functional/pausable_rendering_tests.js b/src/tests/functional/pausable_rendering_tests.js index 2da682d02..e49b84ef8 100644 --- a/src/tests/functional/pausable_rendering_tests.js +++ b/src/tests/functional/pausable_rendering_tests.js @@ -1,6 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { nextBeat } from "../helpers/page" +import { expect, test } from "@playwright/test" test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/pausable_rendering.html") @@ -8,43 +6,41 @@ test.beforeEach(async ({ page }) => { test("pauses and resumes rendering", async ({ page }) => { page.on("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Continue rendering?") + expect(dialog.message()).toEqual("Continue rendering?") dialog.accept() }) await page.click("#link") - await nextBeat() - assert.equal(await page.textContent("h1"), "One") + await expect(page.locator("h1")).toHaveText("One") }) test("aborts rendering", async ({ page }) => { const [firstDialog] = await Promise.all([page.waitForEvent("dialog"), page.click("#link")]) - assert.strictEqual(firstDialog.message(), "Continue rendering?") + expect(firstDialog.message()).toEqual("Continue rendering?") firstDialog.dismiss() - assert.equal(await page.textContent("h1"), "Pausable Rendering") + await expect(page.locator("h1")).toHaveText("Pausable Rendering") }) test("pauses and resumes rendering a Frame", async ({ page }) => { page.on("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Continue rendering?") + expect(dialog.message()).toEqual("Continue rendering?") dialog.accept() }) await page.click("#frame-link") - await nextBeat() - assert.equal(await page.textContent("#hello h2"), "Hello from a frame") + await expect(page.locator("#hello h2")).toHaveText("Hello from a frame") }) test("aborts rendering a Frame", async ({ page }) => { page.on("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Continue rendering?") + expect(dialog.message()).toEqual("Continue rendering?") dialog.dismiss() }) - assert.equal(await page.textContent("#hello h2"), "Pausable Frame Rendering") + await expect(page.locator("#hello h2")).toHaveText("Pausable Frame Rendering") }) diff --git a/src/tests/functional/pausable_requests_tests.js b/src/tests/functional/pausable_requests_tests.js index 56dcdd34d..5bb509123 100644 --- a/src/tests/functional/pausable_requests_tests.js +++ b/src/tests/functional/pausable_requests_tests.js @@ -1,6 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" -import { nextBeat } from "../helpers/page" +import { expect, test } from "@playwright/test" test.beforeEach(async ({ page }) => { await page.goto("/src/tests/fixtures/pausable_requests.html") @@ -8,31 +6,27 @@ test.beforeEach(async ({ page }) => { test("pauses and resumes request", async ({ page }) => { page.once("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Continue request?") + expect(dialog.message()).toEqual("Continue request?") dialog.accept() }) await page.click("#link") - await nextBeat() - assert.equal(await page.textContent("h1"), "One") + await expect(page.locator("h1")).toHaveText("One") }) test("aborts request", async ({ page }) => { page.once("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Continue request?") + expect(dialog.message()).toEqual("Continue request?") dialog.dismiss() }) await page.click("#link") - await nextBeat() page.once("dialog", (dialog) => { - assert.strictEqual(dialog.message(), "Request aborted") + expect(dialog.message()).toEqual("Request aborted") dialog.accept() }) - await nextBeat() - - assert.equal(await page.textContent("h1"), "Pausable Requests") + await expect(page.locator("h1")).toHaveText("Pausable Requests") }) diff --git a/src/tests/functional/preloader_tests.js b/src/tests/functional/preloader_tests.js index 83293342a..bc25969bc 100644 --- a/src/tests/functional/preloader_tests.js +++ b/src/tests/functional/preloader_tests.js @@ -1,5 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { nextBeat } from "../helpers/page" test("preloads snapshot on initial load", async ({ page }) => { @@ -7,14 +6,14 @@ test("preloads snapshot on initial load", async ({ page }) => { await page.goto("/src/tests/fixtures/preloading.html") await nextBeat() - assert.ok( + expect( await page.evaluate(() => { - const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" - const cache = window.Turbo.session.preloader.snapshotCache.snapshots + const preloadedUrl = new URL("http://localhost:9000/src/tests/fixtures/preloaded.html") + const cache = window.Turbo.session.preloader.snapshotCache return preloadedUrl in cache }) - ) + ).toEqual(true) }) test("preloads snapshot on page visit", async ({ page }) => { @@ -26,14 +25,14 @@ test("preloads snapshot on page visit", async ({ page }) => { await page.waitForSelector("#preload_anchor") await nextBeat() - assert.ok( + expect( await page.evaluate(() => { - const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" - const cache = window.Turbo.session.preloader.snapshotCache.snapshots + const preloadedUrl = new URL("http://localhost:9000/src/tests/fixtures/preloaded.html") + const cache = window.Turbo.session.preloader.snapshotCache return preloadedUrl in cache }) - ) + ).toEqual(true) }) test("navigates to preloaded snapshot from frame", async ({ page }) => { @@ -42,12 +41,12 @@ test("navigates to preloaded snapshot from frame", async ({ page }) => { await page.waitForSelector("#frame_preload_anchor") await nextBeat() - assert.ok( + expect( await page.evaluate(() => { - const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" - const cache = window.Turbo.session.preloader.snapshotCache.snapshots + const preloadedUrl = new URL("http://localhost:9000/src/tests/fixtures/preloaded.html") + const cache = window.Turbo.session.preloader.snapshotCache return preloadedUrl in cache }) - ) + ).toEqual(true) }) diff --git a/src/tests/functional/rendering_tests.js b/src/tests/functional/rendering_tests.js index d56f75e9a..e28ffb430 100644 --- a/src/tests/functional/rendering_tests.js +++ b/src/tests/functional/rendering_tests.js @@ -1,5 +1,4 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { clearLocalStorage, disposeAll, @@ -13,7 +12,6 @@ import { propertyForSelector, readEventLogs, scrollToSelector, - selectorHasFocus, sleep, strictElementEquals, textContent, @@ -30,30 +28,30 @@ test("triggers before-render and render events", async ({ page }) => { await page.click("#same-origin-link") const { newBody } = await nextEventNamed(page, "turbo:before-render") - assert.equal(await page.textContent("h1"), "One") + await expect(page.locator("h1")).toHaveText("One") await nextEventNamed(page, "turbo:render") - assert.equal(await newBody, await page.evaluate(() => document.body.outerHTML)) + expect(await newBody).toEqual(await page.evaluate(() => document.body.outerHTML)) }) test("includes isPreview in render event details", async ({ page }) => { await page.click("#same-origin-link") const { isPreview } = await nextEventNamed(page, "turbo:before-render") - assert.equal(isPreview, false) + expect(isPreview).toEqual(false) await nextEventNamed(page, "turbo:render") - assert.equal(await isPreview, false) + expect(await isPreview).toEqual(false) }) test("triggers before-render, render, and load events for error pages", async ({ page }) => { await page.click("#nonexistent-link") const { newBody } = await nextEventNamed(page, "turbo:before-render") - assert.equal(await textContent(page, newBody), "\nCannot GET /nonexistent\n\n\n") + expect(await textContent(page, newBody)).toEqual("\nCannot GET /nonexistent\n\n\n") await nextEventNamed(page, "turbo:render") - assert.equal(await newBody, await page.evaluate(() => document.body.outerHTML)) + expect(await newBody).toEqual(await page.evaluate(() => document.body.outerHTML)) await nextEventNamed(page, "turbo:load") }) @@ -74,9 +72,9 @@ test("reloads when tracked elements change", async ({ page }) => { const reason = await page.evaluate(() => localStorage.getItem("reloadReason")) - assert.equal(pathname(page.url()), "/src/tests/fixtures/tracked_asset_change.html") - assert.equal(await visitAction(page), "load") - assert.equal(reason, "tracked_element_mismatch") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/tracked_asset_change.html") + expect(await visitAction(page)).toEqual("load") + expect(reason).toEqual("tracked_element_mismatch") }) test("reloads when tracked elements change due to failed form submission", async ({ page }) => { @@ -107,10 +105,10 @@ test("reloads when tracked elements change due to failed form submission", async const reason = await page.evaluate(() => localStorage.getItem("reason")) const unloaded = await page.evaluate(() => localStorage.getItem("unloaded")) - assert.equal(pathname(page.url()), "/src/tests/fixtures/rendering.html") - assert.equal(await visitAction(page), "load") - assert.equal(reason, "tracked_element_mismatch") - assert.equal(unloaded, "true") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/rendering.html") + expect(await visitAction(page)).toEqual("load") + expect(reason).toEqual("tracked_element_mismatch") + expect(unloaded).toEqual("true") }) test("before-render event supports custom render function", async ({ page }) => { @@ -125,10 +123,8 @@ test("before-render event supports custom render function", async ({ page }) => }) ) await page.click("#same-origin-link") - await nextBody(page) - const customRendered = await page.locator("#custom-rendered") - assert.equal(await customRendered.textContent(), "Custom Rendered", "renders with custom function") + await expect(page.locator("#custom-rendered")).toHaveText("Custom Rendered") }) test("before-render event supports async custom render function", async ({ page }) => { @@ -158,15 +154,15 @@ test("before-render event supports async custom render function", async ({ page const renderedElement = await page.evaluate(() => localStorage.getItem("renderedElement")) - assert.equal(renderedElement, "Custom Rendered", "renders with custom function") + expect(renderedElement).toEqual("Custom Rendered") }) test("wont reload when tracked elements has a nonce", async ({ page }) => { await page.click("#tracked-nonce-tag-link") await nextBody(page) - assert.equal(pathname(page.url()), "/src/tests/fixtures/tracked_nonce_tag.html") - assert.equal(await visitAction(page), "advance") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/tracked_nonce_tag.html") + expect(await visitAction(page)).toEqual("advance") }) test("reloads when turbo-visit-control setting is reload", async ({ page }) => { @@ -185,18 +181,18 @@ test("reloads when turbo-visit-control setting is reload", async ({ page }) => { const reason = await page.evaluate(() => localStorage.getItem("reloadReason")) - assert.equal(pathname(page.url()), "/src/tests/fixtures/visit_control_reload.html") - assert.equal(await visitAction(page), "load") - assert.equal(reason, "turbo_visit_control_is_reload") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/visit_control_reload.html") + expect(await visitAction(page)).toEqual("load") + expect(reason).toEqual("turbo_visit_control_is_reload") }) test("maintains scroll position before visit when turbo-visit-control setting is reload", async ({ page }) => { await scrollToSelector(page, "#below-the-fold-visit-control-reload-link") - assert.notOk(await isScrolledToTop(page), "scrolled down") + expect(await isScrolledToTop(page)).toEqual(false) await page.evaluate(() => localStorage.setItem("scrolls", "false")) - page.evaluate(() => + await page.evaluate(() => addEventListener("click", () => { addEventListener("scroll", () => { localStorage.setItem("scrolls", "true") @@ -204,22 +200,21 @@ test("maintains scroll position before visit when turbo-visit-control setting is }) ) - page.click("#below-the-fold-visit-control-reload-link") + await page.click("#below-the-fold-visit-control-reload-link") await nextBody(page) const scrolls = await page.evaluate(() => localStorage.getItem("scrolls")) - assert.equal(scrolls, "false", "scroll position is preserved") + expect(scrolls).toEqual("false") - assert.equal(pathname(page.url()), "/src/tests/fixtures/visit_control_reload.html") - assert.equal(await visitAction(page), "load") + expect(pathname(page.url())).toEqual("/src/tests/fixtures/visit_control_reload.html") + expect(await visitAction(page)).toEqual("load") }) test("changes the html[lang] attribute", async ({ page }) => { await page.click("#es_locale_link") - await nextEventNamed(page, "turbo:load") - assert.equal(await page.getAttribute("html", "lang"), "es") + await expect(page.locator("html")).toHaveAttribute("lang", "es") }) test("accumulates asset elements in head", async ({ page }) => { @@ -229,12 +224,12 @@ test("accumulates asset elements in head", async ({ page }) => { await page.click("#additional-assets-link") await nextBody(page) const newElements = await assetElements() - assert.notOk(await deepElementsEqual(page, newElements, originalElements)) + expect(await deepElementsEqual(page, newElements, originalElements)).toEqual(false) await page.goBack() await nextBody(page) const finalElements = await assetElements() - assert.ok(await deepElementsEqual(page, finalElements, newElements)) + expect(await deepElementsEqual(page, finalElements, newElements)).toEqual(true) await disposeAll(...originalElements, ...newElements, ...finalElements) }) @@ -242,37 +237,37 @@ test("accumulates asset elements in head", async ({ page }) => { test("replaces provisional elements in head", async ({ page }) => { const provisionalElements = () => page.$$('head :not(script), head :not(style), head :not(link[rel="stylesheet"])') const originalElements = await provisionalElements() - assert.equal(await page.locator("meta[name=test]").count(), 0) + expect(await page.locator("meta[name=test]").count()).toEqual(0) await page.click("#same-origin-link") await nextBody(page) const newElements = await provisionalElements() - assert.notOk(await deepElementsEqual(page, newElements, originalElements)) - assert.equal(await page.locator("meta[name=test]").count(), 1) + expect(await deepElementsEqual(page, newElements, originalElements)).toEqual(false) + expect(await page.locator("meta[name=test]").count()).toEqual(1) await page.goBack() await nextBody(page) const finalElements = await provisionalElements() - assert.notOk(await deepElementsEqual(page, finalElements, newElements)) - assert.equal(await page.locator("meta[name=test]").count(), 0) + expect(await deepElementsEqual(page, finalElements, newElements)).toEqual(false) + expect(await page.locator("meta[name=test]").count()).toEqual(0) await disposeAll(...originalElements, ...newElements, ...finalElements) }) test("evaluates head stylesheet elements", async ({ page }) => { - assert.equal(await isStylesheetEvaluated(page), false) + expect(await isStylesheetEvaluated(page)).toEqual(false) await page.click("#additional-assets-link") await nextEventNamed(page, "turbo:render") - assert.equal(await isStylesheetEvaluated(page), true) + expect(await isStylesheetEvaluated(page)).toEqual(true) }) test("does not evaluate head stylesheet elements inside noscript elements", async ({ page }) => { - assert.equal(await isNoscriptStylesheetEvaluated(page), false) + expect(await isNoscriptStylesheetEvaluated(page)).toEqual(false) await page.click("#additional-assets-link") await nextEventNamed(page, "turbo:render") - assert.equal(await isNoscriptStylesheetEvaluated(page), false) + expect(await isNoscriptStylesheetEvaluated(page)).toEqual(false) }) test("waits for CSS to be loaded before rendering", async ({ page }) => { @@ -287,15 +282,15 @@ test("waits for CSS to be loaded before rendering", async ({ page }) => { await page.click("#additional-assets-link") - assert.equal(await isStylesheetEvaluated(page), false) - assert.notEqual(await page.textContent("h1"), "Additional assets") + expect(await isStylesheetEvaluated(page)).toEqual(false) + await expect(page.locator("h1")).not.toHaveText("Additional assets") finishLoadingCSS() await nextEventNamed(page, "turbo:render") - assert.equal(await page.textContent("h1"), "Additional assets") - assert.equal(await isStylesheetEvaluated(page), true) + await expect(page.locator("h1")).toHaveText("Additional assets") + expect(await isStylesheetEvaluated(page)).toEqual(true) }) test("waits for CSS to fail before rendering", async ({ page }) => { @@ -310,15 +305,15 @@ test("waits for CSS to fail before rendering", async ({ page }) => { await page.click("#additional-assets-link") - assert.equal(await isStylesheetEvaluated(page), false) - assert.notEqual(await page.textContent("h1"), "Additional assets") + expect(await isStylesheetEvaluated(page)).toEqual(false) + await expect(page.locator("h1")).not.toHaveText("Additional assets") finishLoadingCSS() await nextEventNamed(page, "turbo:render") - assert.equal(await page.textContent("h1"), "Additional assets") - assert.equal(await isStylesheetEvaluated(page), false) + await expect(page.locator("h1")).toHaveText("Additional assets") + expect(await isStylesheetEvaluated(page)).toEqual(false) }) test("waits for some time, but renders if CSS takes too much to load", async ({ page }) => { @@ -334,81 +329,79 @@ test("waits for some time, but renders if CSS takes too much to load", async ({ await page.click("#additional-assets-link") await nextEventNamed(page, "turbo:render") - assert.equal(await page.textContent("h1"), "Additional assets") - assert.equal(await isStylesheetEvaluated(page), false) + await expect(page.locator("h1")).toHaveText("Additional assets") + expect(await isStylesheetEvaluated(page)).toEqual(false) finishLoadingCSS() await nextBeat() - assert.equal(await isStylesheetEvaluated(page), true) + expect(await isStylesheetEvaluated(page)).toEqual(true) }) test("skip evaluates head script elements once", async ({ page }) => { - assert.equal(await headScriptEvaluationCount(page), undefined) + expect(await headScriptEvaluationCount(page)).toEqual(undefined) await page.click("#head-script-link") await nextEventNamed(page, "turbo:render") - assert.equal(await headScriptEvaluationCount(page), 1) + expect(await headScriptEvaluationCount(page)).toEqual(1) await page.goBack() await nextEventNamed(page, "turbo:render") - assert.equal(await headScriptEvaluationCount(page), 1) + expect(await headScriptEvaluationCount(page)).toEqual(1) await page.click("#head-script-link") await nextEventNamed(page, "turbo:render") - assert.equal(await headScriptEvaluationCount(page), 1) + expect(await headScriptEvaluationCount(page)).toEqual(1) }) test("evaluates body script elements on each render", async ({ page }) => { - assert.equal(await bodyScriptEvaluationCount(page), undefined) + expect(await bodyScriptEvaluationCount(page)).toEqual(undefined) await page.click("#body-script-link") await nextEventNamed(page, "turbo:render") - assert.equal(await bodyScriptEvaluationCount(page), 1) + expect(await bodyScriptEvaluationCount(page)).toEqual(1) await page.goBack() await nextEventNamed(page, "turbo:render") - assert.equal(await bodyScriptEvaluationCount(page), 1) + expect(await bodyScriptEvaluationCount(page)).toEqual(1) await page.click("#body-script-link") await nextEventNamed(page, "turbo:render") - assert.equal(await bodyScriptEvaluationCount(page), 2) + expect(await bodyScriptEvaluationCount(page)).toEqual(2) }) test("does not evaluate data-turbo-eval=false scripts", async ({ page }) => { await page.click("#eval-false-script-link") await nextEventNamed(page, "turbo:render") - assert.equal(await bodyScriptEvaluationCount(page), undefined) + expect(await bodyScriptEvaluationCount(page)).toEqual(undefined) }) test("preserves permanent elements", async ({ page }) => { const permanentElement = await page.locator("#permanent") - assert.equal(await permanentElement.textContent(), "Rendering") + await expect(permanentElement).toHaveText("Rendering") await page.click("#permanent-element-link") await nextEventNamed(page, "turbo:render") - assert.ok(await strictElementEquals(permanentElement, await page.locator("#permanent"))) - assert.equal(await permanentElement.textContent(), "Rendering") + expect(await strictElementEquals(permanentElement, await page.locator("#permanent"))).toEqual(true) + await expect(permanentElement).toHaveText("Rendering") await page.goBack() await nextEventNamed(page, "turbo:render") - assert.ok(await strictElementEquals(permanentElement, await page.locator("#permanent"))) + expect(await strictElementEquals(permanentElement, await page.locator("#permanent"))).toEqual(true) }) test("restores focus during page rendering when transposing the activeElement", async ({ page }) => { await page.press("#permanent-input", "Enter") - await nextBody(page) - assert.ok(await selectorHasFocus(page, "#permanent-input"), "restores focus after page loads") + await expect(page.locator("#permanent-input")).toBeFocused() }) test("restores focus during page rendering when transposing an ancestor of the activeElement", async ({ page }) => { await page.press("#permanent-descendant-input", "Enter") - await nextBody(page) - assert.ok(await selectorHasFocus(page, "#permanent-descendant-input"), "restores focus after page loads") + await expect(page.locator("#permanent-descendant-input")).toBeFocused() }) test("before-frame-render event supports custom render function within turbo-frames", async ({ page }) => { @@ -425,35 +418,34 @@ test("before-frame-render event supports custom render function within turbo-fra ) await page.click("#permanent-in-frame-element-link") - await nextBeat() const customRendered = await page.locator("#frame #custom-rendered") - assert.equal(await customRendered.textContent(), "Custom Rendered Frame", "renders with custom function") + await expect(customRendered).toHaveText("Custom Rendered Frame") }) test("preserves permanent elements within turbo-frames", async ({ page }) => { - assert.equal(await page.textContent("#permanent-in-frame"), "Rendering") + await expect(page.locator("#permanent-in-frame")).toHaveText("Rendering") await page.click("#permanent-in-frame-element-link") - await nextBeat() + await nextEventNamed(page, "turbo:frame-load") - assert.equal(await page.textContent("#permanent-in-frame"), "Rendering") + await expect(page.locator("#permanent-in-frame")).toHaveText("Rendering") }) test("restores focus during turbo-frame rendering when transposing the activeElement", async ({ page }) => { await page.press("#permanent-input-in-frame", "Enter") - await nextBeat() + await nextEventNamed(page, "turbo:frame-load") - assert.ok(await selectorHasFocus(page, "#permanent-input-in-frame"), "restores focus after page loads") + await expect(page.locator("#permanent-input-in-frame")).toBeFocused() }) test("restores focus during turbo-frame rendering when transposing a descendant of the activeElement", async ({ page }) => { await page.press("#permanent-descendant-input-in-frame", "Enter") - await nextBeat() + await nextEventNamed(page, "turbo:frame-load") - assert.ok(await selectorHasFocus(page, "#permanent-descendant-input-in-frame"), "restores focus after page loads") + await expect(page.locator("#permanent-descendant-input-in-frame")).toBeFocused() }) test("preserves permanent element video playback", async ({ page }) => { @@ -462,13 +454,13 @@ test("preserves permanent element video playback", async ({ page }) => { await sleep(500) const timeBeforeRender = await videoElement.evaluate((video) => video.currentTime) - assert.notEqual(timeBeforeRender, 0, "playback has started") + expect(timeBeforeRender).not.toEqual(0) await page.click("#permanent-element-link") - await nextBody(page) + await nextEventNamed(page, "turbo:load") const timeAfterRender = await videoElement.evaluate((video) => video.currentTime) - assert.equal(timeAfterRender, timeBeforeRender, "element state is preserved") + expect(timeAfterRender).toEqual(timeBeforeRender) }) test("preserves permanent element through Turbo Stream update", async ({ page }) => { @@ -481,9 +473,8 @@ test("preserves permanent element through Turbo Stream update", async ({ page }) `) }) - await nextBeat() - assert.equal(await page.textContent("#permanent-in-frame"), "Rendering") + await expect(page.locator("#permanent-in-frame")).toHaveText("Rendering") }) test("preserves permanent element through Turbo Stream append", async ({ page }) => { @@ -496,9 +487,8 @@ test("preserves permanent element through Turbo Stream append", async ({ page }) `) }) - await nextBeat() - assert.equal(await page.textContent("#permanent-in-frame"), "Rendering") + await expect(page.locator("#permanent-in-frame")).toHaveText("Rendering") }) test("preserves input values", async ({ page }) => { @@ -514,12 +504,12 @@ test("preserves input values", async ({ page }) => { await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(await propertyForSelector(page, "#text-input", "value"), "test") - assert.equal(await propertyForSelector(page, "#checkbox-input", "checked"), true) - assert.equal(await propertyForSelector(page, "#radio-input", "checked"), true) - assert.equal(await propertyForSelector(page, "#textarea", "value"), "test") - assert.equal(await propertyForSelector(page, "#select", "value"), "2") - assert.equal(await propertyForSelector(page, "#select-multiple", "value"), "2") + expect(await propertyForSelector(page, "#text-input", "value")).toEqual("test") + expect(await propertyForSelector(page, "#checkbox-input", "checked")).toEqual(true) + expect(await propertyForSelector(page, "#radio-input", "checked")).toEqual(true) + expect(await propertyForSelector(page, "#textarea", "value")).toEqual("test") + expect(await propertyForSelector(page, "#select", "value")).toEqual("2") + expect(await propertyForSelector(page, "#select-multiple", "value")).toEqual("2") }) test("does not preserve password values", async ({ page }) => { @@ -530,7 +520,7 @@ test("does not preserve password values", async ({ page }) => { await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(await propertyForSelector(page, "#password-input", "value"), "") + expect(await propertyForSelector(page, "#password-input", "value")).toEqual("") }) test(" clears values when restored from cache", async ({ page }) => { @@ -548,12 +538,12 @@ test(" clears values when restored from cache", async ({ pag await page.click("#reset-input") - assert.equal(await propertyForSelector(page, "#text-input", "value"), "") - assert.equal(await propertyForSelector(page, "#checkbox-input", "checked"), false) - assert.equal(await propertyForSelector(page, "#radio-input", "checked"), false) - assert.equal(await propertyForSelector(page, "#textarea", "value"), "") - assert.equal(await propertyForSelector(page, "#select", "value"), "1") - assert.equal(await propertyForSelector(page, "#select-multiple", "value"), "") + expect(await propertyForSelector(page, "#text-input", "value")).toEqual("") + expect(await propertyForSelector(page, "#checkbox-input", "checked")).toEqual(false) + expect(await propertyForSelector(page, "#radio-input", "checked")).toEqual(false) + expect(await propertyForSelector(page, "#textarea", "value")).toEqual("") + expect(await propertyForSelector(page, "#select", "value")).toEqual("1") + expect(await propertyForSelector(page, "#select-multiple", "value")).toEqual("") }) test("before-cache event", async ({ page }) => { @@ -565,7 +555,7 @@ test("before-cache event", async ({ page }) => { await page.goBack() await nextEventNamed(page, "turbo:load") - assert.equal(await page.textContent("body"), "Modified") + await expect(page.locator("body")).toHaveText("Modified") }) test("mutation record-cache notification", async ({ page }) => { @@ -574,20 +564,20 @@ test("mutation record-cache notification", async ({ page }) => { await nextBody(page) await page.goBack() - assert.equal(await page.textContent("body"), "Modified") + await expect(page.locator("body")).toHaveText("Modified") }) test("error pages", async ({ page }) => { await page.click("#nonexistent-link") - await nextBody(page) - assert.equal(await page.textContent("body"), "\nCannot GET /nonexistent\n\n\n") + + await expect(page.locator("body")).toHaveText("\nCannot GET /nonexistent\n\n\n") }) test("rendering a redirect response replaces the body once and only once", async ({ page }) => { await page.click("#redirect-link") await nextBodyMutation(page) - assert.ok(await noNextBodyMutation(page), "replaces element once") + expect(await noNextBodyMutation(page)).toEqual(true) }) function deepElementsEqual(page, left, right) { diff --git a/src/tests/functional/scroll_restoration_tests.js b/src/tests/functional/scroll_restoration_tests.js index 03bcc66c2..1a6f5763f 100644 --- a/src/tests/functional/scroll_restoration_tests.js +++ b/src/tests/functional/scroll_restoration_tests.js @@ -1,23 +1,22 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { nextBeat, scrollPosition, scrollToSelector } from "../helpers/page" test("landing on an anchor", async ({ page }) => { await page.goto("/src/tests/fixtures/scroll_restoration.html#three") await nextBeat() const { y: yAfterLoading } = await scrollPosition(page) - assert.notEqual(yAfterLoading, 0) + expect(yAfterLoading).not.toEqual(0) }) test("reloading after scrolling", async ({ page }) => { await page.goto("/src/tests/fixtures/scroll_restoration.html") await scrollToSelector(page, "#three") const { y: yAfterScrolling } = await scrollPosition(page) - assert.notEqual(yAfterScrolling, 0) + expect(yAfterScrolling).not.toEqual(0) await page.reload() const { y: yAfterReloading } = await scrollPosition(page) - assert.notEqual(yAfterReloading, 0) + expect(yAfterReloading).not.toEqual(0) }) test("returning from history", async ({ page }) => { @@ -27,5 +26,5 @@ test("returning from history", async ({ page }) => { await page.goBack() const { y: yAfterReturning } = await scrollPosition(page) - assert.notEqual(yAfterReturning, 0) + expect(yAfterReturning).not.toEqual(0) }) diff --git a/src/tests/functional/stream_tests.js b/src/tests/functional/stream_tests.js index 40f464d21..517a528ad 100644 --- a/src/tests/functional/stream_tests.js +++ b/src/tests/functional/stream_tests.js @@ -1,12 +1,8 @@ -import { test } from "@playwright/test" -import { assert } from "chai" +import { expect, test } from "@playwright/test" import { - hasSelector, nextBeat, nextEventNamed, - readEventLogs, - waitUntilNoSelector, - waitUntilText + readEventLogs } from "../helpers/page" test.beforeEach(async ({ page }) => { @@ -17,12 +13,11 @@ test.beforeEach(async ({ page }) => { test("receiving a stream message", async ({ page }) => { const messages = await page.locator("#messages .message") - assert.deepEqual(await messages.allTextContents(), ["First"]) + await expect(messages).toHaveText(["First"]) await page.click("#append-target button") - await nextBeat() - assert.deepEqual(await messages.allTextContents(), ["First", "Hello world!"]) + await expect(messages).toHaveText(["First", "Hello world!"]) }) test("dispatches a turbo:before-stream-render event", async ({ page }) => { @@ -30,24 +25,23 @@ test("dispatches a turbo:before-stream-render event", async ({ page }) => { await nextEventNamed(page, "turbo:submit-end") const [[type, { newStream }, target]] = await readEventLogs(page, 1) - assert.equal(type, "turbo:before-stream-render") - assert.equal(target, "a-turbo-stream") - assert.ok(newStream.includes(`action="append"`)) - assert.ok(newStream.includes(`target="messages"`)) + expect(type).toEqual("turbo:before-stream-render") + expect(target).toEqual("a-turbo-stream") + expect(newStream).toContain(`action="append"`) + expect(newStream).toContain(`target="messages"`) }) test("receiving a stream message with css selector target", async ({ page }) => { const messages2 = await page.locator("#messages_2 .message") const messages3 = await page.locator("#messages_3 .message") - assert.deepEqual(await messages2.allTextContents(), ["Second"]) - assert.deepEqual(await messages3.allTextContents(), ["Third"]) + await expect(messages2).toHaveText(["Second"]) + await expect(messages3).toHaveText(["Third"]) await page.click("#append-targets button") - await nextBeat() - assert.deepEqual(await messages2.allTextContents(), ["Second", "Hello CSS!"]) - assert.deepEqual(await messages3.allTextContents(), ["Third", "Hello CSS!"]) + await expect(messages2).toHaveText(["Second", "Hello CSS!"]) + await expect(messages3).toHaveText(["Third", "Hello CSS!"]) }) test("receiving a message without a template", async ({ page }) => { @@ -57,7 +51,7 @@ test("receiving a message without a template", async ({ page }) => { `) ) - assert.notOk(await waitUntilNoSelector(page, "#messages"), "removes target element") + await expect(page.locator("#messages")).not.toBeVisible() }) test("receiving a message with a