freeCodeCamp 如何对 Docker 本地环境运行 Playwright E2E 测试?
【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp
freeCodeCamp 仓库的端到端测试放在e2e/目录,使用 Playwright 驱动(testDir指向该目录自身),测试对象是本地起好的完整服务栈:MongoDB 副本集、API 容器和 Mailpit 收信服务。这篇文章给出在本地用 Docker 组合起这套环境、并跑通e2e/测试套的完整路径。前提条件来自根目录 package.json 的engines字段:Node.js>=24、pnpm>=10,另外需要可用的 Docker 与 Docker Compose。最终目标是执行pnpm run playwright:run并拿到 HTML 测试报告。
一、准备根目录 .env 文件
Playwright 配置 e2e/playwright.config.ts 顶部会用 dotenv 读取仓库根目录的.env,e2e 用的 compose 覆盖文件 docker/docker-compose.e2e.yml 也通过env_file: ../.env把同一个文件注入 API 容器。如果本地还没有.env,按仓库 devcontainer 初始化脚本 .devcontainer/on-create.sh 的做法复制模板即可:
cp sample.env .envsample.env 中与本场景直接相关的两个值:
HOME_LOCATION=http://localhost:8000—— Playwright 配置的baseURL(未设置时回退为http://127.0.0.1:8000),即前端页面地址;API_LOCATION=http://localhost:3000—— 全局登录步骤访问API_LOCATION + '/signin'的 API 地址。
CI 工作流也是直接把sample.env作为环境变量来源(.github/workflows/e2e-playwright.yml),说明这组示例值足以支撑本地 E2E 运行。
二、构建 fcc-api API 镜像
e2e 覆盖文件中的api服务声明为image: fcc-api,即该镜像必须事先构建好。CI 的build-e2e-api任务(.github/workflows/node.js-tests.yml)使用的命令就是在仓库根目录执行:
docker build -t fcc-api -f docker/api/Dockerfile .Dockerfile 基于node:24-bookworm,内部会执行pnpm install、Prisma 客户端生成和构建,因此这一步耗时较长。副作用:只生成一个名为fcc-api的本地镜像,不改动仓库文件。
三、启动 E2E 服务栈
docker/docker-compose.e2e.yml 文件头部的注释就是官方用法,在仓库根目录执行:
docker compose -f docker/docker-compose.yml -f docker/docker-compose.ports.yml -f docker/docker-compose.e2e.yml up -d三个文件各管一段:
- docker/docker-compose.yml:
db(mongo:8.2,以--replSet rs0启动,带mongosh --eval "db.adminCommand('ping')"健康检查)、setup(一次性容器,初始化副本集rs0)、mailpit(axllent/mailpit收信服务); - docker/docker-compose.ports.yml:向宿主机发布
27017(db)和1025/8025(mailpit),使.env里基于 localhost 的地址在宿主机上可达; - docker/docker-compose.e2e.yml:追加
api服务,使用fcc-api镜像并发布3000:3000。其中强制覆盖MONGOHQ_URL=mongodb://mongodb:27017/freecodecamp?replicaSet=rs0和MAILPIT_HOST=mailpit——文件注释解释了原因:容器内无法通过 localhost 连到这两个服务,必须用 compose 服务名。
启动后可以用docker compose ps检查各服务状态;仓库 devcontainer 的初始化脚本在 MongoDB 未变成可写主节点时,给出的排查动作就是docker compose ps查看服务状态。
四、安装 Playwright 浏览器并启动前端
pnpm install npx playwright install --with-depsplaywright:install-build-tools是根 package.json 中定义的脚本,等价于npx playwright install --with-deps,CI 也执行同一条命令。注意--with-deps会同时安装浏览器所需的系统依赖,可能涉及系统包安装,视环境需要相应权限。
测试访问的前端页面由宿主机进程提供(e2e compose 栈只包含 API 容器)。仓库中两种已文档化的启动方式:
- CI 路径:先
pnpm install与pnpm run build,再执行pnpm run serve:client-ci(后台运行,CI 中为pnpm run serve:client-ci &); - devcontainer 路径:VS Code 任务 “Start freeCodeCamp” 执行
pnpm run develop。
本地 Docker 场景建议跟随 CI 组合:
pnpm run build pnpm run serve:client-ci &前端监听 8000 端口这一点可由多处一致的证据确认:sample.env的HOME_LOCATION=http://localhost:8000、Playwright 配置的默认baseURL,以及 devcontainer 端口表中 8000 标注为 “Client”。
五、播种测试用户
pnpm run seed:certified-user该脚本(根 package.json)依次执行seed:surveys、seed:exams、seed:ms-username,再运行node ./tools/scripts/seed/seed-demo-user --certified-user。副作用是向本地 MongoDB 写入演示与认证用户数据——这正是 E2E 登录流程需要的账号。CI 工作流同样在执行测试前运行这一条命令。
另外,e2e/global-setup.ts 中定义的setup项目会在测试项目之前自动运行:它再次执行node ../tools/scripts/seed/seed-demo-user --certified-user,请求API_LOCATION + '/signin'完成登录,并把会话写入playwright/.auth/certified-user.json。这个文件也是配置中所有测试项目的默认storageState,因此 setup 不通过,后续所有浏览器项目都会失败。
六、运行 Playwright 测试
在仓库根目录执行(CI 使用的确切命令):
pnpm run playwright:run --project=chromium根目录的playwright:run转发到e2e包的 e2e/package.json 中的turbo setup && playwright test,--project参数继续透传给playwright test。配置中定义了chromium、firefox、webkit及 “Mobile Chrome”(Pixel 5)、“Mobile Safari”(iPhone 12)五个测试项目,全部依赖setup;CI 目前只跑 chromium(工作流注释说明待 chromium 稳定后再扩展到其他浏览器),所以本地首跑选--project=chromium最稳妥。
开发时想交互式调试,可选用pnpm run playwright:watch,对应turbo setup && playwright test --ui-port=0。
配置中与运行相关的默认行为(均来自 e2e/playwright.config.ts):
workers: 1,fullyParallel: false;- 单测试
timeout: 15 * 1000(15 秒); - 仅在 CI(
process.env.CI)下启用retries: 2、forbidOnly和maxFailures: 6,本地无重试; webServer配置会在 Mailpit 未运行时执行docker run --rm -p 1025:1025 -p 8025:8025 axllent/mailpit并等待 1025 端口(超时 180 秒);因为 compose 栈已发布这两个端口,reuseExistingServer: true会直接复用已存在的 Mailpit。配置注释说明部分测试会触发 API 发信,需要 Mailpit 接住这些邮件。
七、验证结果
- 登录态产物:
playwright/.auth/certified-user.json被 setup 成功生成(developmentuser 分支还会生成development-user.json),说明 API 可达且种子用户可用; - 运行产物:失败截图(
screenshot: 'only-on-failure')与测试输出位于e2e/playwright/test-results,首次重试时收集 trace; - HTML 报告:
reporter配置输出到e2e/playwright/reporter,CI 也是以这个目录(e2e/playwright/reporter)作为 playwright-report 归档,可在其中查看逐用例的通过/失败明细。
八、已知限制与排查要点
e2e/playwright.config.ts与 compose 栈都依赖根目录.env;缺文件时 baseURL 和 API 地址都会落到默认值或 undefined,登录步骤无法定位服务;- 如果走 devcontainer 路线,
docker-compose.ports.yml是被省略的——docker-compose.ports.yml 的注释解释了原因:devcontainer 中的服务与 db 共享网络命名空间、无法发布端口,.env中的 localhost 在该命名空间内直接可解析。两条路线不要混用同一套 compose 文件组合; - API 容器依赖
db与mailpit先就绪(e2e 覆盖文件里的depends_on),MongoDB 副本集初始化由setup容器完成,若docker compose ps中看到 setup 反复重启,先从这里查起(初始化失败时它会以on-failure:5策略重试)。
【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考