7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
83 lines
3.2 KiB
JavaScript
83 lines
3.2 KiB
JavaScript
/**
|
|
* Seeded Chrome profile for Puppeteer tests.
|
|
*
|
|
* Why this exists (#4430)
|
|
* =======================
|
|
* The CI test credentials (test_admin / testpass123) appear in Chrome's
|
|
* breached-credential database. After a SUCCESSFUL login with such a pair,
|
|
* Chrome's password leak detection opens a tab-modal "password found in a
|
|
* data breach" dialog. In headless the dialog is invisible, but it still
|
|
* swallows ALL real (CDP-dispatched) mouse and keyboard input for that tab,
|
|
* permanently: page.type()/page.click() silently do nothing on every page
|
|
* visited after login, while page.evaluate(), Input.insertText and JS
|
|
* .click() keep working. That is exactly the "CDP input not delivered to
|
|
* /chat/ in headless" failure — /chat/ was a red herring; any tab that
|
|
* performed the login is affected (failed logins and fresh tabs are not).
|
|
*
|
|
* Leak detection has no working command-line switch in current Chrome
|
|
* (--disable-features=PasswordLeakDetection no longer has any effect), so
|
|
* the only reliable off-switch is the profile preference
|
|
* profile.password_manager_leak_detection. This helper creates a throwaway
|
|
* user-data-dir with that pref (plus credentials_enable_service=false to
|
|
* also suppress the save-password bubble) for puppeteer.launch().
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
|
|
const createdDirs = [];
|
|
|
|
/**
|
|
* Create a temporary Chrome user-data-dir whose Default profile disables
|
|
* password leak detection and the password manager. Each call returns a
|
|
* fresh directory, so concurrent browser launches never fight over a
|
|
* profile lock. Directories are best-effort removed on process exit.
|
|
*
|
|
* @returns {string} Absolute path to pass as puppeteer's userDataDir.
|
|
*/
|
|
function createSeededChromeProfile() {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ldr-chrome-profile-'));
|
|
fs.mkdirSync(path.join(dir, 'Default'), { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(dir, 'Default', 'Preferences'),
|
|
JSON.stringify({
|
|
// Pref names map to JSON paths by their dots, so the two
|
|
// password-manager prefs land at different depths on purpose:
|
|
// kCredentialsEnableService is registered as the top-level
|
|
// "credentials_enable_service", while leak detection is
|
|
// "profile.password_manager_leak_detection".
|
|
profile: {
|
|
password_manager_leak_detection: false,
|
|
password_manager_enabled: false,
|
|
},
|
|
credentials_enable_service: false,
|
|
})
|
|
);
|
|
createdDirs.push(dir);
|
|
return dir;
|
|
}
|
|
|
|
function cleanupProfiles() {
|
|
for (const dir of createdDirs.splice(0)) {
|
|
try {
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
} catch (_) {
|
|
// Best effort — CI containers are ephemeral anyway.
|
|
}
|
|
}
|
|
}
|
|
|
|
process.on('exit', cleanupProfiles);
|
|
// 'exit' does not fire on signals (local Ctrl-C, CI step timeouts).
|
|
// Clean up, then re-raise so the default termination behavior — and any
|
|
// other handlers' exit codes — still apply.
|
|
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
process.once(sig, () => {
|
|
cleanupProfiles();
|
|
process.kill(process.pid, sig);
|
|
});
|
|
}
|
|
|
|
module.exports = { createSeededChromeProfile };
|