Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1m13s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 6s
Server / Tests (frappe ${{ matrix.frappe-branch }}) (push) Has been skipped
Server / Resolve frappe matrix (push) Failing after 1s
Frontend / Lint (push) Failing after 1s
Frontend / Production Build (push) Failing after 1s
Server / Coverage Wrap Up (push) Has been skipped
Frontend / Coverage Wrap Up (push) Has been skipped
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import * as fs from 'fs'
|
|
import * as path from 'path'
|
|
import { expect, test as setup } from '@playwright/test'
|
|
|
|
const authFile = 'e2e/.auth/user.json'
|
|
const csrfFile = 'e2e/.auth/csrf.json'
|
|
|
|
/**
|
|
* Authentication setup - runs once before all tests.
|
|
* Logs in via the Frappe API, captures the CSRF token, and saves storage state.
|
|
*/
|
|
setup('authenticate', async ({ page }) => {
|
|
const authDir = path.dirname(authFile)
|
|
if (!fs.existsSync(authDir)) {
|
|
fs.mkdirSync(authDir, { recursive: true })
|
|
}
|
|
|
|
const loginResponse = await page.request.post('/api/method/login', {
|
|
form: {
|
|
usr: process.env.FRAPPE_USER || 'Administrator',
|
|
pwd: process.env.FRAPPE_PASSWORD || 'admin',
|
|
},
|
|
})
|
|
expect(loginResponse.ok()).toBeTruthy()
|
|
|
|
const userResponse = await page.request.get(
|
|
'/api/method/frappe.auth.get_logged_user',
|
|
)
|
|
expect(userResponse.ok()).toBeTruthy()
|
|
const userData = await userResponse.json()
|
|
expect(userData.message).not.toBe('Guest')
|
|
console.log(`Authenticated as: ${userData.message}`)
|
|
|
|
// Load the CRM app so window.frappe.csrf_token is available.
|
|
await page.goto('/crm')
|
|
await page.waitForLoadState('networkidle')
|
|
|
|
// The CRM SPA injects boot keys onto window (see crm/www/crm.html),
|
|
// so the token lives at window.csrf_token.
|
|
const csrfToken = await page.evaluate(() => {
|
|
const w = window as unknown as {
|
|
csrf_token?: string
|
|
frappe?: { csrf_token?: string }
|
|
}
|
|
return w.csrf_token || w.frappe?.csrf_token
|
|
})
|
|
|
|
// A missing token means later API writes would fail with an opaque 417;
|
|
// fail the setup loudly instead of proceeding with no CSRF header.
|
|
expect(csrfToken).toBeTruthy()
|
|
fs.writeFileSync(csrfFile, JSON.stringify({ csrf_token: csrfToken }))
|
|
|
|
await page.context().storageState({ path: authFile })
|
|
})
|