用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/andrewyng/context-hub --skill login-flows命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | login-flows |
| description | Common login automation patterns for web apps using Playwright |
| metadata | {"updated-on":"2026-02-01","source":"community","tags":"browser,automation,playwright,login,testing"} |
Reusable patterns for automating login flows in end-to-end tests.
import { Page } from '@playwright/test';
async function login(page: Page, username: string, password: string) {
await page.goto('/login');
await page.fill('[name="username"]', username);
await page.fill('[name="password"]', password);
await page.click('button[type="submit"]');
await page.waitForURL('/dashboard');
}
For OAuth flows that redirect to an external provider:
async function loginWithOAuth(page: Page) {
await page.goto('/login');
await page.click('text=Sign in with Google');
// Handle the OAuth popup or redirect
await page.fill('input[type="email"]', process.env.TEST_EMAIL!);
await page.click('text=Next');
await page.fill('input[type="password"]', process.env.TEST_PASSWORD!);
await page.click('text=Next');
// Wait for redirect back to app
await page.waitForURL('**/dashboard');
}
Avoid logging in before every test by saving and reusing browser state:
// global-setup.ts — runs once before all tests
import { chromium } from '@playwright/test';
async function globalSetup() {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('/login');
await page.fill('[name="username"]', 'testuser');
await page.fill('[name="password"]', 'testpass');
await page.click('button[type="submit"]');
await page.waitForURL('/dashboard');
// Save signed-in state
await page.context().storageState({ path: './auth.json' });
await browser.close();
}
export default globalSetup;
Then in playwright.config.ts:
export default defineConfig({
globalSetup: './global-setup.ts',
use: {
storageState: './auth.json',
},
});
For test environments with TOTP-based 2FA:
import { authenticator } from 'otplib';
async function loginWithMFA(page: Page, secret: string) {
await login(page, 'user', 'pass');
// Generate TOTP code
const code = authenticator.generate(secret);
await page.fill('[name="totp"]', code);
await page.click('button[type="submit"]');
await page.waitForURL('/dashboard');
}
storageState to avoid repeated logins — it's the single biggest speedup for E2E suitespage.waitForURL() instead of arbitrary waitForTimeout() after login