feat(functional-tests): add pairing E2E test with marionette authority#20119
feat(functional-tests): add pairing E2E test with marionette authority#20119
Conversation
de2e451 to
23dda8b
Compare
| expect(pairUrl).toBeTruthy(); | ||
| expect(pairUrl).toContain('/pair#'); | ||
| expect(pairUrl).toContain('channel_id='); | ||
| if (!pairUrl) throw new Error('pairUrl is null'); |
4a66af3 to
ee5412b
Compare
a9e9176 to
a1dc25e
Compare
Add end-to-end test for the Firefox device pairing flow using a Marionette-driven Firefox authority and Playwright supplicant. - Minimal Marionette TCP client (marionette.ts) - Firefox process manager with temp profile lifecycle (marionette-firefox.ts) - Playwright fixture using bundled Firefox (125+) as Marionette authority - Uses beginOAuthFlow for proper PKCE/keys_jwk registration - Condition-based waits replacing hardcoded sleeps
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| /** | ||
| * End-to-end pairing flow test. |
There was a problem hiding this comment.
This is the most important comment of the PR, we need marionette to access FF internals to get the QR code url. While iterating it turns out you don't need to take a picture and decode the url, you can use the internal libs to get the url.
Once you have the url (channel_id & channel_key) you can build the pairing url and get the flow connected.
| } from '../../lib/pairing-helpers'; | ||
|
|
||
| // Increase timeout — pairing involves launching a separate Firefox + channel negotiation | ||
| test.setTimeout(120_000); |
There was a problem hiding this comment.
Locally this test takes about 60s to complete,=
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| /** | ||
| * Minimal Marionette protocol client over raw TCP. |
There was a problem hiding this comment.
I probably would have never thought of doing it this way, but I like it. This introduces zero deps and just talks to marionette via tcp.
| export { expect } from '@playwright/test'; | ||
|
|
||
| /** | ||
| * Fetch the pairing channel server URI from the target's well-known config. |
There was a problem hiding this comment.
Lots of tokens were spent trying to figure this out. Turns out that the channel server on local/stage/prod are all different 🤷🏽
Because
This pull request
lib/marionette.ts) to drive a real Firefox instance for the authority side of pairinglib/marionette-firefox.ts) that launches Playwright's bundled Firefox with Marionette enabled, manages temp profiles, and cleans up on teardownlib/fixtures/pairing.ts) that wires the Marionette authority into the test lifecycle usingfirefox.executablePath()tests/pairing/pairingFlow.spec.ts) exercising: OAuth sign-in viabeginOAuthFlow→ start pairing → channel handshake → authority approval → supplicant confirm → both sides completelib/pairing-constants.ts) and helpers (lib/pairing-helpers.ts) with condition-based waits (no hardcoded sleeps)CI_WAF_TOKENbypass header in CI for stage/production runsIssue that this pull request solves
Closes: https://mozilla-hub.atlassian.net/browse/FXA-9501
Checklist
Put an
xin the boxes that applyOther information (Optional)
How to test:
Note: Expect ~30-35s per run.
MARIONETTE_HEADLESS=falseshows the authority Firefox window;--headedshows the Playwright supplicant browser.est.