You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions中Playwright无法访问Spring Web应用问题排查

问题描述

在GitHub Actions工作流中使用Playwright Java对Spring Web应用执行端到端(E2E)测试,预期流程为启动Spring应用后台运行,再执行Playwright测试。日志显示curl可成功访问http://localhost:8080,但Playwright访问时出现net::ERR_CONNECTION_REFUSED错误。

工作流配置

name: Run Spring Petclinic and Tests
on: [push]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/playwright:v1.32.0-focal

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
          cache: 'maven'

      - name: Checkout spring-petclinic
        uses: actions/checkout@v3
        with:
          repository: spring-projects/spring-petclinic

      - name: Build and Run Spring Petclinic
        run: |
          ./mvnw spring-boot:run &
          sleep 300
          curl http://localhost:8080 -I

      - name: Checkout current repository
        uses: actions/checkout@v3

      - name: Build & Install
        run: ./mvnw -B install -D skipTests --no-transfer-progress

      - name: Install Playwright
        run: ./mvnw exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps"

      - name: Run tests
        run: ./mvnw test

Playwright错误日志

com.microsoft.playwright.PlaywrightException: 
Error {
  message='net::ERR_CONNECTION_REFUSED at http://localhost:8080/
=========================== logs ===========================
navigating to "http://localhost:8080/", waiting until "load"
============================================================
  name='Error
  stack='Error: net::ERR_CONNECTION_REFUSED at http://localhost:8080/
=========================== logs ===========================
navigating to "http://localhost:8080/", waiting until "load"
============================================================
    at FrameSession._navigate (/tmp/playwright-java-15764527846349711028/package/lib/server/chromium/crPage.js:509:35)
    at async Frame._gotoAction (/tmp/playwright-java-15764527846349711028/package/lib/server/frames.js:537:28)
    at async ProgressController.run (/tmp/playwright-java-15764527846349711028/package/lib/server/progress.js:92:22)
    at async FrameDispatcher.goto (/tmp/playwright-java-15764527846349711028/package/lib/server/dispatchers/frameDispatcher.js:75:103)
    at async DispatcherConnection.dispatch (/tmp/playwright-java-15764527846349711028/package/lib/server/dispatchers/dispatcher.js:312:22)
}

测试代码

@Test
void sampleTest() {
    try (Playwright playwright = Playwright.create()) {
        Browser browser = playwright.chromium().launch();
        Page page = browser.newPage();
        page.navigate("http://localhost:8080");
        assertThat(page.title()).isEqualTo("PetClinic :: a Spring Framework demonstration");
    }
}
问题分析与解决

核心问题

  1. Spring应用进程被终止:GitHub Actions的每个run步骤是独立shell会话,后台运行的./mvnw spring-boot:run &会在当前步骤结束时被终止,后续执行测试时应用已停止。
  2. 代码目录被覆盖:Checkout current repository步骤会覆盖之前检出的spring-petclinic代码,导致后续无法维护应用运行环境。

修复后的工作流配置

name: Run Spring Petclinic and Tests
on: [push]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/playwright:v1.32.0-focal

    steps:
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
          cache: 'maven'

      # 将测试代码检出到独立目录,避免覆盖Spring项目
      - name: Checkout test repository
        uses: actions/checkout@v3
        with:
          path: test-repo

      # 检出spring-petclinic到根目录
      - name: Checkout spring-petclinic
        uses: actions/checkout@v3
        with:
          repository: spring-projects/spring-petclinic

      # 构建并持久化启动Spring应用,确保跨步骤运行
      - name: Build and Start Spring Petclinic
        run: |
          ./mvnw clean package -DskipTests
          # 使用nohup确保进程在步骤结束后持续运行
          nohup java -jar target/spring-petclinic-*.jar &
          # 循环检测应用状态,替代固定sleep的低效等待
          until curl -s http://localhost:8080 > /dev/null; do
            echo "Waiting for Spring app to start..."
            sleep 5
          done
          curl http://localhost:8080 -I

      # 切换到测试代码目录执行测试流程
      - name: Run Playwright Tests
        working-directory: test-repo
        run: |
          ./mvnw -B install -DskipTests --no-transfer-progress
          ./mvnw exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install --with-deps"
          ./mvnw test

关键修改说明

  • 进程持久化:用nohup java -jar ... &替代./mvnw spring-boot:run &,避免Spring应用在步骤结束时被终止。
  • 目录隔离:将测试代码与Spring项目分别检出到不同目录,防止代码覆盖。
  • 智能等待:通过循环curl检测应用状态,确保应用真正就绪后再执行测试,比固定sleep更高效可靠。
  • 指定工作目录:测试步骤中通过working-directory明确执行测试代码的Maven命令。

额外优化建议

  • 为Spring应用指定固定端口,避免端口冲突;
  • 测试代码中添加页面加载超时机制,防止无限等待;
  • 启用Maven缓存,加快重复构建速度。

内容的提问来源于stack exchange,提问作者Vitali Plagov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:50:41