Testcafe client function failing "An error occurred in ClientFunction code: ReferenceError: _from2 is not defined"

Testcafe client function failing "An error occurred in ClientFunction code: ReferenceError: _from2 is not defined"

我正在尝试使用客户端函数来访问页面上 child 元素中的值,不一定是本例中的那些值,但使用提供的 testcafe 选择器很难找到的值。

在定义页面 object 模型时,我希望能够访问多个 iFrame 模式上的“下一步”、“返回”和“保存”按钮,它们可以在 DOM 上具有不同的位置,具体取决于模式视图,并且没有 ID(产品是旧产品)。

但是它们确实都遵循相似的模式,它们都是一个跨度的 child 个元素,并且包含带有它们名称的显示文本和标题,通过 chrome Dev Tools Console 我可以使用类似于以下内容的内容访问它们

Array.from(document.querySelectorAll('span')).find(el => el.textContent === "Next")

然而,当我尝试在 testcafe 中将其作为客户端函数调用时出现错误,以下是基于我的方法但针对 testcafe 站点的示例,它给出了相同的错误。

import { Selector } from 'testcafe';
import { ClientFunction } from 'testcafe';
fixture `Client Function`
.page `https://devexpress.github.io/testcafe/documentation/test-api/selecting-page-elements/selectors/functional-style-selectors.html`;

const query = ClientFunction(() =>  Array.from(document.querySelectorAll('a')).find(el => el.textContent === "Filter DOM Nodes"));

test('Test query', async t => {
      const queryResult = await query();
      await t
      .click(Selector(queryResult))
      .wait(1500);
});

这个错误对我来说相当神秘:

  1) An error occurred in ClientFunction code:

      ReferenceError: _from2 is not defined

      Browser: Chrome 71.0.3578 / Mac OS X 10.13.6

          6 |    .page

   `https://devexpress.github.io/testcafe/documentation/test-api/selecting-page-elements/selectors/functional-style-selectors.html`;
          7 |
          8 |const query = ClientFunction(() =>
      Array.from(document.querySelectorAll('a')).find(el => el.textContent
      === "Filter DOM Nodes"));
          9 |
         10 |test('Login and register user', async t => {
       > 11 |      const queryResult = await query();
         12 |      await t
         13 |      .click(Selector(queryResult))
         14 |      .wait(1500);
         15 |});
         16 |

         at query (/Users/david/Documents/testcafe/demo/query.js:11:33)
         at test (/Users/david/Documents/testcafe/demo/query.js:10:1)
         at markeredfn

   (/usr/local/lib/node_modules/testcafe/src/api/wrap-test-function.js:17:28)
         at <anonymous>
      (/usr/local/lib/node_modules/testcafe/src/api/wrap-test-function.js:7:5)
         at fn
      (/usr/local/lib/node_modules/testcafe/src/test-run/index.js:239:19)
         at TestRun._executeTestFn
      (/usr/local/lib/node_modules/testcafe/src/test-run/index.js:235:38)
         at _executeTestFn
      (/usr/local/lib/node_modules/testcafe/src/test-run/index.js:284:24)



 1/1 failed (5s)

有谁知道这是一个合法的错误还是实施错误?谢谢 - 也非常欢迎任何指点!

您可以像这样重写 ClientFunction:

const query = ClientFunction(() =>  {
    const results = [];
    const allLinks = document.querySelectorAll('a');
    allLinks.forEach(link => results.push(link));
    const foundElement = results.find(el => el.textContent === "Filter DOM Nodes");
    return foundElement;
});

但是你会收到另一个错误:

ClientFunction cannot return DOM elements. Use Selector functions for this purpose.

ClientFunction 中的代码在浏览器中执行。

调用此 ClientFunction 并获取其结果的代码在浏览器外部的 NodeJS 进程中执行。

您要实现的目标称为对象编组。您正在尝试将位于浏览器进程中的 DOM 对象传输到另一个单独的进程中。这只能通过序列化来实现,但 DOM 对象不可序列化。

ClientFunction 中的 return 语句必须 return POJO(普通旧 Javascript 对象)。

您可以像这样使用 Selector 对象来实现相同的目的:

const nextButton = Selector('span')
  .find('a')
  .withAttribute('title', 'NEXT')
  .withText('NEXT');
await t.click(nextButton);

如果您需要除属性和 textContent 之外的特殊过滤,您可以这样编写选择器:

const nextButton = Selector('span')
    .find('a')
    .filter((link) => {
        if (/* some condition processed on link element */) {
            // this link element is the one to be clicked
            return true;
        }
        return false;
    });