Commit Graph
12 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5.5 373d5c9dc7 fix(web-app-odoo): run the onion suite on full Chromium so its origin is secure
The shared Playwright config passes --unsafely-treat-insecure-origin-as-secure
for every .onion origin in the environment, but Playwright's default
chrome-headless-shell ignores that switch. On the tor axis the odoo origin
therefore stayed an insecure context: navigator.clipboard was undefined and
Odoo 20's onboarding tour crashed with "Cannot read properties of undefined
(reading 'writeText')" and "Cannot destructure property 'TourInteractive'",
opening error dialogs that the addon specs read as a missing module (odoo#2,
swarm tor, main run 38038541631).

When ODOO_BASE_URL is an onion URL the odoo specs now use channel "chromium",
the full Chromium build in the Playwright image, and block service workers;
clearnet runs keep every option unchanged. The worker is blocked because a
secure context lets Odoo register /web/service-worker.js, whose fetch handler
answers a failed navigation with a cached page or /odoo/offline: gotoOnion
would get a 200 instead of the transport error it retries on. The switch stays
in the role: a use.channel in the shared config would also reach the Firefox
launch of onion-test.js, which rejects it with "Unsupported firefox channel",
and would move every other role's onion run to a browser none of them was
tested on.

Verified with Playwright 1.63 in the runner's staging layout and the real
odoo specs: an onion ODOO_BASE_URL resolves channel "chromium" and
serviceWorkers "block", also for the contexts _shared.js creates itself, and
launches chromium-<rev>/chrome-linux64/chrome; a clearnet one, and HEAD's
specs on onion, keep the headless shell and "allow". All spec files stay on
one worker, which the suite's one-worker test requires. Against Odoo 20's
service worker with a dropped connection, full Chromium returned the cached
/odoo page with status 200, while with the worker blocked page.goto threw
net::ERR_CONNECTION_FAILED as the headless shell does. In the v1.64.0 image
full Chromium made no :443 attempt to an onion host and the onion origin
reported isSecureContext with crypto.subtle, which the headless shell did not.
A local deploy of web-app-odoo variant 2 over Tor ran the odoo suite on
/ms-playwright/chromium-1248/chrome-linux64/chrome and passed all seven addon
specs, the one-worker test and the guest flow without a retry; in the variant
0 round the suites of the other roles kept chrome-headless-shell.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
kevinveenbirkenbachandClaude Opus 5 4e053aa321 fix(odoo): sign in once for the addon suite instead of once per spec
Each of the seven addon specs opened a fresh context and ran the full SSO
round-trip. Over Tor that is roughly twelve minutes apiece, and odoo 0 of run
31340965955 died on 'Test timeout of 600000ms exceeded' inside
gotoOnion -> loginToOdoo -> contacts.spec.js:13.

authenticatedContext caches the storage state after the first login and restores
it for later callers. A restored state that no longer renders the web client is
discarded and the full login runs, so an expired session degrades to today's
behaviour rather than failing the spec.

Coverage is not reduced: the SSO flow keeps its own dedicated tests in
playwright.spec.js:98 and :160 (admin and biber, log in / verify ui / log out),
which this change does not touch. The seven addon logins were repetition of an
already-covered path, and no addon spec asserts anything about the login or
needs an anonymous session. What does change is isolation -- the specs now share
one restored session instead of each starting clean.

The TEST_E2E_PLAYWRIGHT_ONION_TEST_TIMEOUT bump belongs in this commit: four
specs lost their own test.setTimeout(resolveTimeout(180_000)), which resolved to
900s on an onion. Without the bump those four would regress from 900s to 600s.

Cause B is untouched: the global ONION_RUN_TIMEOUT of 5400s left eight tests
unstarted. The cache should relieve it, but that is arithmetic on measured
single-login times, not an observed run, and raising a timeout that spans every
onion role needs its own measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 15:52:07 +02:00
kevinveenbirkenbachandClaude Opus 4.8 35dee215c8 test(playwright): route all timeouts through resolveTimeout for onion-compat
Add the global TIMEOUT_FACTOR and a shared timeouts.js helper: resolveTimeout(base) scales by TIMEOUT_FACTOR and, over a .onion target, an extra multiplier, so Tor's per-request latency no longer trips hard-coded timeouts. Migrate every raw timeout in the specs (timeout:/timeout=/setTimeout/waitForTimeout) to resolveTimeout, stage the helper in all three staging paths, and add test_no_raw_timeouts to forbid raw numeric timeouts. Clearnet behaviour is unchanged (factor 1: resolveTimeout(N) === N).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 10:38:06 +02:00
kevinveenbirkenbachandClaude Opus 4.8 46a1acdf81 fix(ci): fix odoo sale_management spec and harden flaky deploys
odoo: sale_management.spec.js asserted `breadcrumb.or(appTitle)` without
`.first()`; when the Sales module installs correctly BOTH the menu brand
and the breadcrumb render, so `.or()` resolved to 2 elements and
`toBeVisible()` raised a strict-mode violation — failing the success case.
Add `.first()` (matching the same file's createQuotation locator).

nextcloud: the GitLab OAuth provisioning hard-`raise`d when no Organization
existed yet (default org is seeded asynchronously). Resolve/create it
defensively and add `retries/until` so a transient not-yet-seeded window no
longer fails the whole deploy.

jenkins: the deploy-lockdown service stop had no retry; under load systemd
intermittently refused with "Transaction is destructive". Add `retries/until`
so the transient contention is ridden out.

moodle: the shared `compose up` handler had no retry; a transient missing
external network (central DB stack still creating it) failed the deploy. Add
`retries/until`, matching the handler's existing compose-pull pattern.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:49:26 +02:00
kevinveenbirkenbachandClaude Opus 4.8 0f18678d31 fix(odoo): collapse stock.spec inventory-identity locator to one element
stock.spec.js applied .first() to each .or() operand (breadcrumb and appTitle) before combining them, so breadcrumb.or(appTitle) was a union of two locators that resolved to 2 visible elements (the stock.menu_stock_root brand link AND the 'Inventory Overview' breadcrumb) — expect().toBeVisible() requires exactly one match and threw a Playwright strict-mode violation. The two matches actually PROVE the stock module installed; the assertion message's 'module failed to install' premise was wrong. Mirror the passing account.spec.js pattern: drop the per-branch .first() and apply a single .first() after .or(). The assertion intent (Inventory identity must render) is preserved — no green-wash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 19:23:57 +02:00
kevinveenbirkenbachandClaude Opus 4.8 00f0f9a4ed test(odoo): navigate the account spec to /odoo/invoicing (the real account.move action)
The account addon spec opened /odoo/accounting (the journal dashboard, which in Odoo 19 has no .o_account_dashboard and not the asserted invoice vocabulary) and timed out even though the account module is installed. Navigate to /odoo/invoicing — the canonical account.move customer-invoices action — and assert the invoices list/kanban plus account-specific vocabulary (customer invoice / register payment / invoice date / tax excluded). Verified green live against Odoo 19 via 'make compose-playwright role=web-app-odoo'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 11:17:58 +02:00
kevinveenbirkenbachandClaude Opus 4.8 900e224348 test(odoo): assert account-specific surface, not a generic Odoo shell
The account addon spec asserted bare .o_control_panel/.o_breadcrumb, which render on every Odoo page, so it passed green even when the account module was enabled-but-not-installed. Require Accounting domain vocabulary (Customer Invoices / Vendor Bills / Chart of Accounts / Journal Entries) and text-gate the generic containers, mirroring the crm/stock specs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 02:50:58 +02:00
kevinveenbirkenbachandClaude Opus 4.8 eeb7f0cc15 test(web-app-odoo): stock spec asserts the Inventory module + operations action
Replace the generic surface check with the Inventory app identity, no invalid-action
error, the stock.picking operations dashboard, and stock-specific operation types
(Receipts/Deliveries/Internal Transfers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 17fa250e24 test(web-app-odoo): sale_management spec asserts the Sales module + quotations action
Replace the generic surface check with the Sales app identity (breadcrumb/title),
the sale.order quotations list/kanban action, and the New create button.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 14a3a1a6d2 test(web-app-odoo): crm spec asserts the CRM module is installed and its pipeline renders
Replace the generic surface check with no-error-page + the CRM control panel and a
CRM-specific surface (lead/opportunity kanban, New, Pipeline) plus CRM domain
vocabulary, proving the crm module loaded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 319e86fc07 test(web-app-odoo): account spec asserts the Accounting module is installed
Replace the generic web-client surface check with module-specific signals: no Odoo
error dialog, the Accounting/Invoicing app brand in the navbar, and an
account-specific top menu (Customers/Vendors/Chart of Accounts).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8e92f15f6a test(addons): require a Playwright spec for every addon; add 87 per-addon specs
Add tests/lint/ansible/services/test_addons_playwright_spec.py requiring roles/<role>/files/playwright/addons/<id>.spec.js for EVERY addon of EVERY role — no mechanism auto-exempt and no # nocheck escape. Ship the 87 per-addon specs (gated via skipUnlessAddonEnabled so they skip cleanly when the addon is disabled in the current variant), the test-e2e-playwright addon-gating harness (addon-gating.js, playwright.config.js, recursive 02_run_one.yml), the shared odoo helper, and the ADDON_<ID>_ENABLED flags in the six playwright.env.j2 templates. Relax test_env_file_schema to skip Jinja-templated keys in the ADDON loop. Doc updates (suppression.md, requirements/026) follow in a separate commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:16:54 +02:00