-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathglobal-setup.ts
More file actions
119 lines (101 loc) · 3.72 KB
/
global-setup.ts
File metadata and controls
119 lines (101 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
* Runs once before any tests; saves storageState to playwright/.auth/user.json.
* Not shown as a test row in the HTML report (unlike a setup project).
*/
import * as fs from "fs";
import * as path from "path";
import {
chromium,
firefox,
webkit,
type Browser,
type FullConfig,
type Page,
} from "@playwright/test";
const authFile = path.join(__dirname, "playwright", ".auth", "user.json");
/** Match PLAYWRIGHT_BROWSER in playwright.config.ts */
async function launchBrowser(): Promise<Browser> {
const headless = !!process.env.CI;
const browser = (process.env.PLAYWRIGHT_BROWSER ?? "msedge").toLowerCase();
if (browser === "firefox") return firefox.launch({ headless });
if (browser === "webkit") return webkit.launch({ headless });
if (browser === "msedge")
return chromium.launch({ channel: "msedge", headless });
return chromium.launch({ headless });
}
/** Host substrings that mean we are still on Microsoft / Entra sign-in, not SharePoint. */
const LOGIN_HOST_MARKERS = [
"login.microsoftonline.com",
"login.microsoft.com",
"login.live.com",
"aadcdn.msauth.net",
"autologon.microsoftazuread-sso.com",
];
function hostnameOf(url: string): string {
try {
return new URL(url).hostname.toLowerCase();
} catch {
return "";
}
}
function stillOnLoginHost(url: string): boolean {
const host = hostnameOf(url);
if (!host) return true;
return LOGIN_HOST_MARKERS.some((m) => host.includes(m.replace(/^www\./, "")));
}
async function waitOutOfLoginFlow(page: Page, targetUrl: string): Promise<void> {
const targetHost = hostnameOf(targetUrl);
await page.waitForURL((url) => !stillOnLoginHost(url.href), { timeout: 300_000 });
if (targetHost) {
try {
if (hostnameOf(page.url()) !== targetHost) {
await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 180_000 });
}
} catch {
await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 180_000 });
}
}
await page.waitForLoadState("domcontentloaded", { timeout: 120_000 }).catch(() => {});
}
export default async function globalSetup(_config: FullConfig) {
fs.mkdirSync(path.dirname(authFile), { recursive: true });
const shouldRefresh = process.env.E2E_REFRESH_AUTH === "1";
if (fs.existsSync(authFile) && !shouldRefresh) return;
const targetUrl = process.env.SHAREPOINT_PAGE_URL?.trim();
if (!targetUrl) {
throw new Error(
"Set SHAREPOINT_PAGE_URL in .env before running tests."
);
}
const browser = await launchBrowser();
try {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 180_000 });
console.info(
"[global-setup] Complete sign-in (+ MFA if prompted) in the browser until you see your SharePoint page, then resume in Playwright Inspector (Continue)."
);
await page.pause();
try {
await waitOutOfLoginFlow(page, targetUrl);
} catch {
if (stillOnLoginHost(page.url())) {
throw new Error(
"[global-setup] Still on Microsoft sign-in after resume. Finish MFA and wait until the address bar shows your SharePoint URL, then Continue again."
);
}
await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 180_000 });
await waitOutOfLoginFlow(page, targetUrl);
}
if (stillOnLoginHost(page.url())) {
throw new Error(
"[global-setup] Refusing to save auth: still on a Microsoft login URL. Complete MFA until SharePoint loads."
);
}
await page.waitForLoadState("networkidle", { timeout: 120_000 }).catch(() => {});
await context.storageState({ path: authFile });
await context.close();
} finally {
await browser.close();
}
}