我遇到了一个问题,我的 Playwright 端到端测试在本地计算机上运行得很好,但在 GitHub Actions 中执行时始终失败。我的设置涉及使用 App Router、TypeScript、Playwright 进行测试和 GitHub Actions for CI 的 Next.js 14 应用程序。
当地环境:
GitHub Actions 环境:
ubuntu-latest
代码概述:
import { test, expect } from "@playwright/test";
import { mkdirSync } from "fs";
import { dirname } from "path";
const authFile = "playwright/.auth/user.json";
test("test", async ({ page }) => {
mkdirSync(dirname(authFile), { recursive: true });
await page.goto("http://localhost:3000/api/auth/signin?csrf=true");
await page.getByRole("button", { name: "Sign in with Azure Active" }).click();
await page.getByPlaceholder("Email, phone, or Skype").click();
await page
.getByPlaceholder("Email, phone, or Skype")
.fill(process.env.PLAYWRIGHT_EMAIL ?? "");
await page.getByRole("button", { name: "Next" }).click();
await page.getByPlaceholder("Password").click();
await page
.getByPlaceholder("Password")
.fill(process.env.PLAYWRIGHT_PASSWORD ?? "");
await page.getByRole("button", { name: "Sign in" }).click();
try {
const yesButton = page.getByRole("button", { name: "Yes" });
await yesButton.waitFor({ state: "visible", timeout: 10000 });
await yesButton.click();
} catch (error) {
console.log(
"The 'Yes' button was not found or not clickable within the time limit."
);
}
await page.goto("http://localhost:3000/home");
await page.context().storageState({ path: authFile });
});
import { test, expect } from "@playwright/test";
test("Authenticated root route redirects to home page", async ({ page }) => {
await page.goto("http://localhost:3000/home");
await expect(page).toHaveURL("http://localhost:3000/home");
await page.goto("http://localhost:3000/");
await expect(page).toHaveURL("http://localhost:3000/home");
});
test("Unauthenticated access redirects to login page for root and home routes", async ({ page }) => {
await page.context().clearCookies();
await page.goto("http://localhost:3000/");
await expect(page).toHaveURL("http://localhost:3000/login");
await page.goto("http://localhost:3000/home");
await expect(page).toHaveURL("http://localhost:3000/login");
});
import { defineConfig, devices } from "@playwright/test";
import dotenv from "dotenv";
import path from "path";
dotenv.config({ path: path.resolve(__dirname, ".env.local") });
export default defineConfig({
testDir: "./e2e-tests",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: "html",
use: {
trace: "on-first-retry",
},
projects: [
{ name: "setup", testMatch: "setup.ts" },
{
name: "chromium",
use: {
...devices["Desktop Chrome"],
storageState: "playwright/.auth/user.json",
},
dependencies: ["setup"],
},
{
name: "firefox",
use: {
...devices["Desktop Firefox"],
storageState: "playwright/.auth/user.json",
},
dependencies: ["setup"],
},
{
name: "webkit",
use: {
...devices["Desktop Safari"],
storageState: "playwright/.auth/user.json",
},
dependencies: ["setup"],
},
],
webServer: {
command: "npm run dev",
url: "http://127.0.0.1:3000",
reuseExistingServer: !process.env.CI,
},
});
playwright.yml
):name: Playwright Tests
on:
pull_request:
jobs:
end-to-end-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
env:
PLAYWRIGHT_EMAIL: ${{ secrets.PLAYWRIGHT_EMAIL }}
PLAYWRIGHT_PASSWORD: ${{ secrets.PLAYWRIGHT_PASSWORD }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID}}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET}}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID}}
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET}}
NEXTAUTH_URL: ${{ secrets.NEXTAUTH_URL}}
run: npm run test:e2e
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
问题:
测试在 GitHub Actions 上失败,并出现以下错误:
Error: Timed out 5000ms waiting for expect(locator).toHaveURL(expected)
Expected string: "***/home"
Received string: "***/login"
这表明身份验证步骤在 CI 环境中可能无法正常工作。然而,相同的设置在本地运行得非常好。
采取的故障排除步骤:
问题:
为什么我的 Playwright 测试在本地通过但在 GitHub Actions 中失败?我在配置或环境设置方面是否缺少某些内容可能会导致这种差异?任何帮助或指示将不胜感激。
您已设置
trace: "on-first-retry",
和 retries: process.env.CI ? 2 : 0,
。调试问题的最简单方法是下载 CI 中最后一步中保存的 HTML 报告。
如果您不知道如何下载 GitHub 工件,请阅读本文 https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/downloading-workflow -文物
然后打开 HTML 报告,找到失败的测试,并将选项卡切换到“重试 #1”。在跟踪查看器中,您将看到到底发生了什么。以下是有关跟踪查看器的文章https://playwright.dev/docs/trace-viewer
您的存储状态文件可能是在没有会话 cookie 的情况下创建的。登录后您可能需要等待一段时间,例如。等到您看到个人资料图片。 在本地,您可以拥有更快的机器,它会创建。