javascript - 使用 Puppeteer 访问 React 状态

标签 javascript reactjs puppeteer

我有一个 React 应用程序正在运行。我想知道是否可以使用 Puppeteer 访问状态值。

例如,在 React 中我有:
const [gridBlocks, setGridBlocks] = useState([])
此值稍后更新为设置 gridBlocks到一个值数组。

然后,使用 Puppeteer 我有:

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://localhost:3000/', {
    waitUntil: 'networkidle2'
  });

  // Can I get access to React and other javascript values now?
  // Something like console.log(await page.evaluate(() => <are React variables available here>));
  // Another way?

await browser.close();
})();
gridBlocks state 有我想循环通过的值来更新 UI 并抓取每个值的屏幕截图。我不知道 gridBlocks 是什么值是提前的,所以我不能只是在我的 Puppeteer 脚本中“硬编码”它们。我真的很喜欢能够从加载的页面中读取它,来自 page.goto .

我见过的大多数文章都是关于测试的,它们都通过了props到组件。我想直接从加载的页面中阅读......如果可能的话。

谢谢!

最佳答案

我在 puppeteer 上找到了一种快速而肮脏的方法。首先,您需要从 chrome 中获取扩展文件。这种方法比从 github 等克隆 react 存储库要快。

有两个主要步骤,

  • 加载扩展和开发工具。
  • 欺骗 devtools 选择组件。


  • 第一步:
  • 首次安装Chrome extension source viewer
  • 现在下载 React Developers Tools 的 zip 文件.
  • 现在解压到你的项目中作为一个文件夹,我选择了extension为名。

  • 加载扩展,确保 保持开发工具打开 .
    const browser = await puppeteer.launch({
        headless: false,
        devtools: true,
        args: [
          '--disable-extensions-except=./extension/',
          '--load-extension=./extension/',
        ]
    });
    

    打开 react 页面,确保 已满载 .
    const page = await browser.newPage();
    await page.goto('http://localhost:3000', {waitUntil: 'networkidle0'});
    

    现在,我们将从根元素中找到子元素,并使用 devtools 中使用的内部命令。

    waitFor 也很重要。我们应该给它一些时间来初始化选择。
    await page.evaluate(()=>{
        const rootElement = document.querySelector('#root').childNodes[0];
        __REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent.selectNode(rootElement);
    })
    
    await page.waitFor(1000);
    

    最后,我们在 中得到了这个特定元素的状态。 $r ,
    const data = await page.evaluate(()=>{
        return $r;
    })
    

    我不能在节点上下文上做很多事情,但我相信你可以使用它来修改和执行不同的东西。

    完整的代码,
    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch({
        headless: false,
        devtools: true,
        args: [
          '--disable-extensions-except=./extension/',
          '--load-extension=./extension/',
        ]
      });
      const page = await browser.newPage();
      await page.goto('http://localhost:3000', {waitUntil: 'networkidle0'});
    
      await page.evaluate(()=>{
        const rootElement = document.querySelector('#root').childNodes[0];
        __REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent.selectNode(rootElement);
      })
    
      await page.waitFor(1000);
    
      const data = await page.evaluate(()=>{
        return $r;
      })
    
      console.log(data)
    })();
    

    这是示例 react 应用程序,
    import React, { useState } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    export default Example;
    

    enter image description here

    笔记:
  • 如果您不打开 devtools 或选择节点,它将无法工作。
  • 它可能不适用于当前 1.19 版本的 headless 模式。
  • 关于javascript - 使用 Puppeteer 访问 React 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57929192/

    相关文章:

    javascript - JS 命令不允许字母,只允许数字(disc bot)

    javascript - 错误 : Evaluation failed: ReferenceError: res is not defined

    javascript - React.js,查看源码是空的,对SEO不好吗?

    javascript - 与 typescript react 来初始化空状态的正确方法是什么

    javascript - 忽略 Puppeteer arg "--remote-debugging-port=0"

    testing - Jest + puppeteer 最佳架构实践

    javascript - 使用按钮调用 HTML 中的 javascript 文件

    javascript - 如何使最后一个 <li> 坚持特定高度的父级 <ul> 的页脚?

    javascript - 为什么 componentDidUpdate 看不到新插入的 dom 节点?

    Reactjs 更新状态中数组中的单个元素