8000 test(browser): stop browser scenarios flaking on slow external requests and LiveView joins by mwoods79 · Pull Request #700 · huddlz-hq/huddlz · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"absinthe_phoenix": {:hex, :absinthe_phoenix, "2.0.6", "e61bc749efdaea188595bf5404005ae7a3f739a1c85d132588f52d5c9585442a", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "dbf0316a40e397d2f46e1093bfff88ccf9543e81ed7a96bfe01dcae26b220f33"},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.10", "c9e207235aaa8a086a5db6801a9bebaea035f7b5a2703cb98d962646ef70c76f", [:mix], [{:absinthe, "~> 1.7", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "489ac1951c8e4128571141c60a0669a720619bc161f801a8c6be8cfaf7ab0979"},
"ash": {:hex, :ash, "3.37.3", "cb8f91b0bf27410252325daaf9cbb9159035dda7b38da021b35db5b08a2be4bc", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.14", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 1.0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.7.6 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.3", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "33817c3231c72f6d09ca1d7e715c654e7f9e70a895a89013b28fc3e93fea7bb1"},
"ash_ai": {:hex, :ash_ai, "1.5.0", "ead7ed49a024f4d401885a152673d4c3f8a16f1e5a839260627be492f79c6326", [:mix], [{:ash, ">= 3.33.6 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_authentication, "~> 4.8 or ~> 5.0-rc", [hex: :ash_authentication, repo: "hexpm", optional: true]}, {:ash_json_api, ">= 1.4.27 and < 2.0.0-0", [hex: :ash_json_api, repo: "hexpm", optional: false]}, {:ash_oban, "~> 0.5", [hex: :ash_oban, repo: "hexpm", optional: true]}, {:ash_phoenix, "~> 2.0", [hex: :ash_phoenix, repo: "hexpm", optional: true]}, {:ash_postgres, "~> 2.5", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:open_api_spex, "~> 3.0", [hex: :open_api_spex, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:plug, "~> 1.17", [hex: :plug, repo: "hexpm", optional: true]}, {:req_llm, "~> 1.29", [hex: :req_llm, repo: "hexpm", optional: true]}], "hexpm", "c5052cb3c05517f62e91ccb50847eab9312746474f62c34bc0f447d52153fa4c"},
"ash_ai": {:hex, :ash_ai, "1.5.1", "4a167b811ddb7456f20170b24ac6b1a89494654228395e426155f6eb4f706bf3", [:mix], [{:ash, ">= 3.33.6 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_authentication, "~> 4.8 or ~> 5.0-rc", [hex: :ash_authentication, repo: "hexpm", optional: true]}, {:ash_json_api, ">= 1.4.27 and < 2.0.0-0", [hex: :ash_json_api, repo: "hexpm", optional: false]}, {:ash_oban, "~> 0.5", [hex: :ash_oban, repo: "hexpm", optional: true]}, {:ash_phoenix, "~> 2.0", [hex: :ash_phoenix, repo: "hexpm", optional: true]}, {:ash_postgres, "~> 2.5", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:open_api_spex, "~> 3.0", [hex: :open_api_spex, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:plug, "~> 1.17", [hex: :plug, repo: "hexpm", optional: true]}, {:req_llm, "~> 1.29", [hex: :req_llm, repo: "hexpm", optional: true]}], "hexpm", "be6b1f2d1012ecd32fd8ed4a2bd3974aa1a277271afa3b9eee2838581172b5f4"},
"ash_archival": {:hex, :ash_archival, "2.0.5", "092ea6a4fda7453841ad72b2f7dc4585a25c1b11d88cc8109494b4736d26f4bf", [:mix], [{:ash, "~> 3.34", [hex: :ash, repo: "hexpm", optional: false]}], "hexpm", "76683df98e640df43ca1114eb2c02ed0b679843a91ae1f00bccde913fcaf714e"},
"ash_authentication": {:hex, :ash_authentication, "4.15.1", "dbc2a4c34c6d25ad3f3c29eb85478c14f3635f9c9e6e9b83cfcf2e95b6aac2aa", [:mix], [{:argon2_elixir, "~> 4.0", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, ">= 2.6.8 and < 3.0.0-0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:assent, "> 0.2.0 and < 0.3.0", [hex: :assent, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:finch, "~> 0.19", [hex: :finch, repo: "hexpm", optional: false]}, {:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.5", [hex: :joken, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}], "hexpm", "c4fdf86762a3b645fa258fb847409228b977e4cf9d90b8d4e12a102c4fbf5d13"},
"ash_authentication_phoenix": {:hex, :ash_authentication_phoenix, "2.17.4", "5138ca9e78234ac72c756447e2f000adf2110060f377d06064b847b8f0c1729a", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_authentication, "~> 4.15", [hex: :ash_authentication, repo: "hexpm", optional: false]}, {:ash_phoenix, ">= 2.3.11 and < 3.0.0-0", [hex: :ash_phoenix, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:gettext, "~> 0.26 or ~> 1.0", [hex: :gettext, repo: "hexpm", optional: true]}, {:igniter, ">= 0.5.25 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_html_helpers, "~> 1.0", [hex: :phoenix_html_helpers, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:slugify, "~> 1.3", [hex: :slugify, repo: "hexpm", optional: false]}], "hexpm", "758b3bc555f28759171d988effb5400d75c56da779ad6fd55305294a2e705964"},
Expand Down
4 changes: 2 additions & 2 deletions test/browser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The command builds the actual app assets, starts the test endpoint and Chromium,

Browser scenarios live in `features/`, their steps in `steps/`, and Cucumber hooks in `support/`. `browser_features_test.exs` supplies explicit feature/step/support globs to Cucumber. The existing fast root and its steps are loaded only by the normal test runner. No Cucumber fork or second library is needed. Use descriptive tags such as `@calendar_browser`; `@browser` conflicts with the adapter's browser-selection option.

Keep this suite serial: its SQL sandbox ownership and global Mox stubs are shared with HTTP/LiveView processes. Do not add `@async` or extra workers without changing that fixture strategy. Each scenario gets a fresh browser context. Authentication uses a signed session cookie; apart from password recovery, these are not sign-in UI tests. Places/geocoding are deterministic stubs, with no external service credentials needed. Browser contexts use `America/New_York`; `@mobile` selects a 320×720 viewport.
Keep this suite serial: its SQL sandbox ownership and global Mox stubs are shared with HTTP/LiveView processes. Do not add `@async` or extra workers without changing that fixture strategy. Each scenario gets a fresh browser context. Authentication uses a signed session cookie; apart from password recovery, these are not sign-in UI tests. Places/geocoding are deterministic stubs, with no external service credentials needed. The browser never reaches the internet, so a slow third party cannot delay the load event: Google Fonts requests are answered with Inter's Latin subset from `test/fixtures/fonts`, so text measures as it does in production, and every other `https://` request, such as a Maps embed, gets an empty local response. Browser contexts use `America/New_York`; `@mobile` selects a 320×720 viewport.

Browser setup uses the adapter's public `Case.do_setup_all/1` and `Case.do_setup/1` functions because Cucumber creates the ExUnit modules. The hook supplies a compatible module name for diagnostic filenames, preserving the scenario name. SQL sandbox HTTP metadata and the LiveView allowance hook are enabled only in test builds, before authentication queries.

Expand All @@ -59,4 +59,4 @@ Screenshots and traces are captured for every attempt under `_build/browser/scre
assets/node_modules/.bin/playwright show-trace _build/browser/traces/<trace.zip>
```

Assertions wait for observable browser state instead of sleeping. JavaScript used in steps observes layout, image loading, or native form submissions; it does not implement the application behavior. The failed-cover scenario intentionally requests a missing image, so its expected 404 is not a suite-wide console failure.
Assertions wait for observable browser state instead of sleeping. Steps use `Huddlz.Test.BrowserHelpers.visit/2`, which also waits for the page's LiveView to connect; with PhoenixTest's own `visit`, a key pressed before the join render can be lost. After a full page load that `visit` did not make, such as a plain form post, call `await_live_view/1` before interacting. JavaScript used in steps observes layout, image loading, or native form submissions; it does not implement the application behavior. The failed-cover scenario intentionally requests a missing image, so its expected 404 is not a suite-wide console failure.
2 changes: 1 addition & 1 deletion test/browser/steps/calendar_day_sheet_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserCalendarDaySheetSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

step "I am going to {string} on the 17th of next month", %{args: [title]} = context do
attendee = generate(user(role: :user))
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/calendar_timezone_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserCalendarSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

step "I attend a Denver huddl late on July 15", context do
attendee = generate(user(role: :user))
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/copy_huddl_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserCopyHuddlSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

step "I opened a copied huddl on my phone", context do
owner = generate(user(role: :user))
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/cover_crop_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserCoverCropSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

require Ash.Query

Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/cover_upload_progress_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserCoverUploadSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

alias Huddlz.Storage.GroupImages

Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/discover_navigation_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserDiscoverNavigationSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [evaluate: 3]

step "a public huddl titled {string} is upcoming", %{args: [title]} = context do
Expand Down
10 changes: 8 additions & 2 deletions test/browser/steps/email_confirmation_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserEmailConfirmationSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import Swoosh.TestAssertions

step "I have hidden the reminder for my unconfirmed address in a browser", context do
Expand All @@ -22,7 +22,13 @@ defmodule BrowserEmailConfirmationSteps do
end

step "I request confirmation from my profile", context do
Map.put(context, :conn, click_button(context.conn, "Resend confirmation"))
# Resending is a plain form post that reloads the profile.
conn =
context.conn
|> click_button("Resend confirmation")
|> await_live_view()

Map.put(context, :conn, conn)
end

step "a confirmation email is sent to my current address", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/group_cover_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserCoverSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [evaluate: 3]

alias Huddlz.Storage.Local
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/huddl_photos_steps.exs < 10BC8 /clipboard-copy>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserPhotoSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

step "I am viewing my completed huddl in the browser", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/keyboard_focus_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserKeyboardFocusSteps do
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import Huddlz.Test.MoxHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

step "I am signed in and looking at my groups in a browser", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/location_keyboard_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule BrowserLocationKeyboardSteps do
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import Huddlz.Test.MoxHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [type: 3, press: 3, evaluate: 3]

step "I have opened my profile in a browser", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/member_menu_steps.exs
10BC8
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserMemberMenuSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

step "I have opened a group's roster in a browser", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/mobile_rsvp_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserMobileRsvpSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

step "I am viewing an upcoming huddl in a narrow browser", context do
owner = generate(user(display_name: "Sam Rivera"))
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/notification_preferences_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserNotificationPreferencesSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [click: 3]

step "I have opened my notification preferences in a browser", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/organizer_keyboard_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserOrganizerSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

step "I have opened a new huddl as its group organizer", context do
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/overview_cards_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserOverviewCardsSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

alias Huddlz.Communities.HuddlAttendee

Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/report_review_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserReportReviewSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]

alias Huddlz.Accounts
alias PhoenixTest.Playwright
Expand Down
3 changes: 2 additions & 1 deletion test/browser/steps/share_links_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ defmodule BrowserShareLinksSteps do

import ExUnit.Assertions
import Huddlz.Generator
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import Huddlz.Test.BrowserHelpers, only: [visit: 2]

step "I am viewing a public {string} to share", %{args: [page]} = context do
owner = generate(user())
Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/sidebar_scroll_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule BrowserSidebarScrollSteps do
import ExUnit.Assertions
import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

@sidebar "document.querySelector('#mobile-navigation-drawer')"
Expand Down
3 changes: 2 additions & 1 deletion test/browser/steps/sign_in_return_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule BrowserSignInReturnSteps do
use Cucumber.StepDefinition

import Huddlz.Generator
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import Huddlz.Test.BrowserHelpers, only: [visit: 2]
import ExUnit.Assertions
import Swoosh.TestAssertions, only: [set_swoosh_global: 0]

Expand Down
2 changes: 1 addition & 1 deletion test/browser/steps/social_schedule_steps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule BrowserSocialScheduleSteps do

import Huddlz.Generator
import Huddlz.Test.BrowserHelpers
import PhoenixTest
import PhoenixTest, except: [visit: 2]
import PhoenixTest.Playwright, only: [press: 3]

step "I am editing a social connection as its owner", context do
Expand Down
45 changes: 44 additions & 1 deletion test/browser/support/hooks.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,49 @@ defmodule BrowserHooks do
# Cucumber's generated module atoms lack the Elixir prefix expected by
# the adapter's artifact filenames. Keep the original scenario name.
driver_context = Map.put(context, :module, __MODULE__)
Map.merge(context, Map.new(BrowserCase.do_setup(driver_context)))
context = Map.merge(context, Map.new(BrowserCase.do_setup(driver_context)))
answer_external_requests_locally(context.conn)
context
end

@inter_url "https://fonts.gstatic.com/s/inter/v20/inter-latin.woff2"

# Inter's Latin subset as Google Fonts serves it: one variable font for every
# weight the layout links.
@inter_css """
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300 700;
font-display: swap;
src: url(#{@inter_url}) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
"""

# Pages link Google Fonts and embed Google Maps. A slow reply from Google
# holds the load event that visit waits for, so every external request is
# answered locally: Inter from a fixture, so layouts measure as they do in
# production, and anything else with an empty response.
defp answer_external_requests_locally(conn) do
{:ok, _} =
PlaywrightEx.BrowserContext.route(
conn.context_id,
# Playwright resolves a bare "https://**" to "https://**/", which only
# matches URLs ending in a slash.
"https://*/**",
fn route, request ->
{:ok, _} = PlaywrightEx.Route.fulfill(route, response(request.url))
end,
timeout: 5_000
)
end

defp response("https://fonts.googleapis.com/" <> _),
do: [content_type: "text/css", body: @inter_css]

defp response(@inter_url),
do: [content_type: "font/woff2", path: "test/fixtures/fonts/inter-latin.woff2"]

defp response(_url), do: [content_type: "text/plain"]
end
Loading
Loading
0