Сбой клиентской функции Testcafe «Произошла ошибка в коде ClientFunction: ReferenceError: _from2 не определено» - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь использовать клиентскую функцию для доступа к значениям дочерних элементов на странице, не обязательно тех, которые в этом примере, но которые трудно найти с помощью предоставленных селекторов testcafe.

При определенииобъектная модель страницы. Я хочу иметь доступ к кнопкам «Далее», «Назад» и «Сохранить» на нескольких модалах iFrame, они могут иметь разные местоположения в DOM в зависимости от модального вида и не иметь идентификаторов (товар старый).

Однако все они следуют схожему шаблону, все они будут дочерними элементами диапазона и содержат текст и заголовок дисплея с их именем, через 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)

Кто-нибудьзнать, является ли это допустимой ошибкой или ошибкой реализации?Спасибо - любые указатели также приветствуются!

1 Ответ

0 голосов
/ 26 января 2019

Вы можете переписать 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 вне браузера.

То, что вы пытаетесь достичь, называется объектом Marshalling. Вы пытаетесь перенести объект DOM, который находится в процессе браузера, в другой отдельный процесс. Это может быть достигнуто только через сериализацию, но объекты DOM не сериализуемы.

Оператор return внутри ClientFunction должен возвращать 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;
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...