Capybara测试使用无头铬未阅读React代码

发布于 2025-02-08 07:59:20 字数 4040 浏览 2 评论 0原文

问题

在我的Rails/React应用程序中使用Capybara进行E2E测试时,每当JavaScript使用React时,它都会难以执行代码。 < div ID =“ root”></div>在代码正确地呈现本地和docker时保持空。我也在本地进行了Capybara测试。奇怪的是,如果我添加document.getElementById(“ root”)。innertext =“ foo bar”它将运行javaScript,并且不知道如何执行react deactdom。渲染位或只是没有。在针对刺激代码运行测试时,它会正确渲染。为了娱乐,我降级为16,但遇到了同样的问题。

背景:

我们使用vite js捆绑了我不认为与之相关的JavaScript,但绝对可能是相关的。该应用程序在高山码头环境中运行,但我可以在本地重现它,因此我认为它的特定环境无关。轨道路线是空的端点,它提供一个空的HTML页面,上面有#Root Div,以相应地进行水合和路线。我们不使用React-Rails GEM。在HTML页面的输出中,资产都指向正确的JS文件,并且这些文件中确实存在代码。

代码

Capybara测试的主要运行时代码。我包括了我使用Capybara测试测试的小反应代码和print page.html的输出的代码。

app/javascript/entrypoints/test.jsx

import React from "react"
import ReactDOM from "react-dom"

// If this is uncommented, this line runs correctly but is not
// replaced by the "Hello World" in the `render` method
// document.getElementById("root").innerText = "Foo bar"

// This never gets run or is run incorrectly
ReactDOM.render(
  <div>Hello World</div>,
  document.getElementById("root")
)

test.html.haml(是的,我知道Haml很糟糕)

!!!
%html{lang: :en}
  %head
    = vite_client_tag
    = vite_react_refresh_tag
    = vite_javascript_tag "test.jsx"

  %body
    #root

react_test_spec.rb

require "rails_helper"

RSpec.describe "Testing react", type: :feature, js: true do
  describe "just checking", :with_csrf do
    before { visit test_home_path }
    subject { page }

    it "renders react" do
      print page.html
      expect(page).to have_content "Hello World"
    end
  end
end

>打印Page.html输出

<html lang="en"><head>
<script src="/vite-test/assets/test.92ee76c9.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite-test/assets/jsx-dev-runtime.ddafb254.js" as="script" crossorigin="anonymous">
</head>
<body>
<div id="root"></div>
</body></html>

配置/设置代码。 vite配置等等。

软件包

    // react related packages
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "6",

    // vite related packages
    "stimulus-vite-helpers": "^3.0.0",
    "vite": "^2.9.1",
    "vite-plugin-ruby": "^3.0.9",
    "vite-plugin-stimulus-hmr": "^3.0.0",
    "@vitejs/plugin-react": "^1.3.2",

    // babel related packages
    "@babel/core": "^7.0.0-0",
    "@babel/preset-react": "^7.16.7",
    "@babel/preset-typescript": "^7.17.12",
    "@babel/eslint-parser": "^7.17.0",
    "@babel/plugin-transform-runtime": "^7.18.2",
    "@babel/preset-env": "^7.17.10",
    "babel-jest": "^27.5.1",
    "babel-plugin-macros": "^3.1.0",

/

Capybara.register_driver :chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument("--headless")
  options.add_argument("--no-sandbox")
  options.add_argument("--disable-dev-shm-usage")
  options.add_argument("--window-size=1400,1400")

  Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: [options])
end

Capybara.javascript_driver = :chrome_headless

版本,

export default defineConfig({
  build: {
    sourcemap: true,
  },
  plugins: [RubyPlugin(), react(), StimulusHMR()],
})

Capybara /code>

{
  "all": {
    "sourceCodeDir": "app/javascript",
    "watchAdditionalPaths": []
  },
  "development": {
    "autoBuild": true,
    "publicOutputDir": "vite-dev",
    "port": 3036
  },
  "test": {
    "autoBuild": true,
    "publicOutputDir": "vite-test",
    "port": 3037
  }
}

dockerfile.development中的一些软件包。还使用Chromedriver在本地重复了此问题

RUN apk add \
  build-base \
  chromium \
  chromium-chromedriver \

Problem

When running e2e tests with Capybara in my Rails/React app, whenever the javascript uses React, it has trouble executing the code. <div id="root"></div> remains empty while the code renders properly locally and in docker. I've duplicated this running the capybara tests locally as well. What is odd is that if I add a document.getElementById("root").innerText = "Foo bar" it runs the javascript and either doesn't know how to execute the ReactDOM.render bit or just doesn't. When running tests against Stimulus code, it renders properly. For funsies, I downgraded to react 16 but had the same issue.

Background:

We use Vite js to bundle the javascript which I don't think is related but definitely could be. The app runs in an alpine docker environment but I can reproduce it locally so I don't think its specific environment related. Rails routes are empty endpoints that serves an empty html page with a #root div for React to hydrate and route accordingly. We're not using the react-rails gem. In the output of the html page, the assets are all pointing at the correct js files and the code does exist in those files.

Code

The main runtime code for capybara tests. I've included the code for the small react snippet I tested with the capybara test and the output of the print page.html.

app/javascript/entrypoints/test.jsx

import React from "react"
import ReactDOM from "react-dom"

// If this is uncommented, this line runs correctly but is not
// replaced by the "Hello World" in the `render` method
// document.getElementById("root").innerText = "Foo bar"

// This never gets run or is run incorrectly
ReactDOM.render(
  <div>Hello World</div>,
  document.getElementById("root")
)

test.html.haml (yes, I know haml is awful)

!!!
%html{lang: :en}
  %head
    = vite_client_tag
    = vite_react_refresh_tag
    = vite_javascript_tag "test.jsx"

  %body
    #root

react_test_spec.rb

require "rails_helper"

RSpec.describe "Testing react", type: :feature, js: true do
  describe "just checking", :with_csrf do
    before { visit test_home_path }
    subject { page }

    it "renders react" do
      print page.html
      expect(page).to have_content "Hello World"
    end
  end
end

print page.html output

<html lang="en"><head>
<script src="/vite-test/assets/test.92ee76c9.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite-test/assets/jsx-dev-runtime.ddafb254.js" as="script" crossorigin="anonymous">
</head>
<body>
<div id="root"></div>
</body></html>

Config/setup code. Package versions, capybara/vite configuration, and etc.

package.json

    // react related packages
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "6",

    // vite related packages
    "stimulus-vite-helpers": "^3.0.0",
    "vite": "^2.9.1",
    "vite-plugin-ruby": "^3.0.9",
    "vite-plugin-stimulus-hmr": "^3.0.0",
    "@vitejs/plugin-react": "^1.3.2",

    // babel related packages
    "@babel/core": "^7.0.0-0",
    "@babel/preset-react": "^7.16.7",
    "@babel/preset-typescript": "^7.17.12",
    "@babel/eslint-parser": "^7.17.0",
    "@babel/plugin-transform-runtime": "^7.18.2",
    "@babel/preset-env": "^7.17.10",
    "babel-jest": "^27.5.1",
    "babel-plugin-macros": "^3.1.0",

capybara.rb

Capybara.register_driver :chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument("--headless")
  options.add_argument("--no-sandbox")
  options.add_argument("--disable-dev-shm-usage")
  options.add_argument("--window-size=1400,1400")

  Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: [options])
end

Capybara.javascript_driver = :chrome_headless

vite.config.ts

export default defineConfig({
  build: {
    sourcemap: true,
  },
  plugins: [RubyPlugin(), react(), StimulusHMR()],
})

vite.json

{
  "all": {
    "sourceCodeDir": "app/javascript",
    "watchAdditionalPaths": []
  },
  "development": {
    "autoBuild": true,
    "publicOutputDir": "vite-dev",
    "port": 3036
  },
  "test": {
    "autoBuild": true,
    "publicOutputDir": "vite-test",
    "port": 3037
  }
}

some packages in Dockerfile.development. Also duplicated this issue locally using chromedriver

RUN apk add \
  build-base \
  chromium \
  chromium-chromedriver \

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2025-02-15 07:59:20

您的JS资产可能在开发模式和测试模式中构建不同 - 听起来您有一个阻止水合的JS错误。在您的测试中添加暂停,以非头部模式运行,然后查看JS/网络错误的开发人员控制台

Your JS assets are likely built differently in dev and test modes - and this sounds like you have a JS bug which is preventing the hydration. Add a pause to your test, run it in non-headless mode and look at the developer console for JS/network errors

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文