fix(ui): keep the E2E suites off the first-run redirect and pick the invite role (#13091)

This commit is contained in:
Alejandro Bailo authored and GitHub committed 2026-10-19 15:58:16 +02:00
1 parent 1783527c11
commit ba0e78188b
5 files changed
+43 -17

No files matched your search

+20
View File
@@ -38,6 +38,26 @@ export abstract class BasePage {
await this.page.reload();
}
/**
* An empty tenant redirects each fresh browser context to the add-provider
* wizard once. Suites expect a plain landing, so mark that first run as done
* with the browser-wide key (the per-tenant one is only written by the app).
* Written right away when the page is already on an app origin, and
* registered as an init script for every later document load, whatever the
* origin: localStorage is per origin and the Registry fixture profiles serve
* the app from several ports. sign-up.spec covers the redirect itself with a
* brand-new tenant.
*/
async skipFirstRunRedirect(): Promise<void> {
const markHandled = () => {
window.localStorage.setItem("prowler.onboarding.first-run", "true");
};
await this.page.addInitScript(markHandled);
if (/^https?:/.test(this.page.url())) {
await this.page.evaluate(markHandled);
}
}
async goBack(): Promise<void> {
await this.page.goBack();
}
+15 -2
View File
@@ -720,11 +720,24 @@ export class ProvidersPage extends BasePage {
).toBeVisible({ timeout: 10000 });
}
// The admin role comes preselected; only the email is needed.
async sendTeammateInvitation(email: string): Promise<void> {
// The form preselects a role only when the tenant has one named exactly
// "admin"; the E2E tenant's is "e2e_admin", so pick the role explicitly.
async sendTeammateInvitation(
email: string,
rolePattern: RegExp = /admin/i,
): Promise<void> {
await this.wizardModal
.getByRole("textbox", { name: /Teammate email/i })
.fill(email);
// Radix Select: the trigger is a combobox and its options render in a portal.
const roleSelect = this.wizardModal.getByRole("combobox", {
name: "Select a role",
});
await roleSelect.click();
const option = this.page.getByRole("option", { name: rolePattern }).first();
await expect(option).toBeVisible({ timeout: 10000 });
await option.click();
await expect(roleSelect).not.toContainText("Select a role");
const send = this.page.getByRole("button", {
name: "Send invitation",
exact: true,
+2 -2
View File
@@ -1101,7 +1101,7 @@
2. Click "Add Provider" button
3. Select AWS provider type
4. Select the "I don't have access, invite a teammate" option
5. Fill the teammate email (the admin role comes preselected)
5. Fill the teammate email and pick a role that can manage providers (the form preselects one only when the tenant has a role named exactly `admin`; the E2E tenant's is `e2e_admin`)
6. Click "Send invitation"
7. Verify the confirmation and the invitation link
8. Click "Done"
@@ -1115,7 +1115,7 @@
### Key verification points
- The invite option is visible on the AWS step for the admin user
- "Send invitation" is enabled once a valid email is typed
- "Send invitation" is enabled once a valid email is typed and a role is selected
- Confirmation text "Invitation sent to {email}" is visible
- The accept link contains `/invitation/accept?invitation_token=`
- The wizard modal is closed after "Done"
+3
View File
@@ -28,6 +28,9 @@ test.describe.serial("Registry", () => {
!fixtureMode,
"Registry browser acceptance is available only through the self-contained fixture profile.",
);
// The saved manager state carries the first-run marker for the enabled
// profile's origin only; the flag-off and Local profiles serve other ports.
await new RegistryPage(page).skipFirstRunRedirect();
await controlledRegistryFixture.reset();
// Exercise the real media CSP without contacting the Registry service.
await page.route(
+3 -13
View File
@@ -198,6 +198,9 @@ export class SignInPage extends BasePage {
*/
async loginAndVerify(credentials: SignInCredentials): Promise<void> {
await this.goto();
// Like the auth setups: the E2E tenant owns no providers, so a fresh
// context would otherwise land on the add-provider wizard, not Overview.
await this.skipFirstRunRedirect();
await this.login(credentials);
await this.verifySuccessfulLogin();
}
@@ -401,17 +404,4 @@ export class SignInPage extends BasePage {
await this.verifySuccessfulLogin();
await this.page.context().storageState({ path: storagePath });
}
/**
* An empty tenant redirects each fresh browser context to the add-provider
* wizard once. Suites expect a plain landing, so mark that first run as done
* with the browser-wide key (the per-tenant one is only written by the app)
* before signing in; sign-up.spec covers the redirect itself with a brand-new
* tenant. Call it on a page already on the app origin.
*/
async skipFirstRunRedirect(): Promise<void> {
await this.page.evaluate(() => {
window.localStorage.setItem("prowler.onboarding.first-run", "true");
});
}
}