Pull to refresh

Comments 19

хочу пример
«как хотели» и «как получилось, потому что, оказывается, вот что...»
пример от задачи зависит, самое креативное, что приходилось делать, это инжектирование на страницу до загрузки кода декоратора addEventListener, который логирует все листенеры и оборачивает передаваемую функцию в доп логгер, далее отлов событий через внутренние коммуникации и соответствующие реакции уже на загруженном сайте. Плюсы очевидны, таким образом можно добраться и контролировать код, который активируется через анонимные самозапускающиеся функции и в обычном случае к нему доступа нет.
даже спорить не буду, я в начале статьи написал про аналоги. Для меня плюсы простота в использовании, использование хромиума, модульность, прозрачность кода.

Не могли бы вы вкратце описать принцип работы evaluate? Метод сериализуется через toString и передаётся на сторону electron-а, где eval-ится? Т.е. всё также как и в casper, slimer?

evalute -> evalute_now -> child.call('javascript', source, done) передается код функции как строка, под капотом call эмит в чилд процесс с контролем доставки -> parent.respondTo('javascript'… -> win.webContents.executeJavaScript(src);
эта цепочка работает с очередью и возвращает в прмис данные.
Любой метод типа .click .type .wait можно рассматривать как частный случай работы evaluate, можно посмотреть в lib/actions.js
Отдельно про передачу функции:
var source = template.execute({ src: String(js_fn), args: args});
this.child.call('javascript', source, done);
под капотом модуль minstache, с шаблоном, куда инжектится функция (как текст)
смотри файл lib/javascript.js

Спасибо. Не ожидал такого подробного ответа. Мне бы хватило простого "да" ) Спросил потому, что у casper.js (slimer, phantom) примерно такой же подход. Очень неудобно. Но, похоже, ввиду того, что по другому никак, с этим приходится мириться.

я отношусь к этому как к транспорту, на счет неудобства, оно же под капотом, о нем просто надо знать и не более того. Получить данные со страницы просто.
let text = await nightmare.evaluate((selector)=>{ rerueen document.querySelector(selector).textContent ;}, '#elem-id'); 
console.log(text);

по сути транспорт связывает код в исполняемом файле с кодом на обрабатываемой странице, никаких вермешелей коллбеков не требуется, все читабельно и просто.
Но тут опять же на вкус и цвет фломастеры разные.

В идеальном случае же:


  • можно было бы использовать ту версию JS, коей располагает nodeJS, а не, скажем, es5. Правда тут можно прикрутить что-нибудь вроде babelEvaluate
  • stack-trace-ы ошибок в evaluate-методе показывали не какую-то бесполезную муть, а конкретную строку в тесте. Тут в принципе тоже можно пошаманить с console.trace на уровне самого Nightmare.
  • возможность использовать замыкания, а не дублировать одно и тоже дважды. Но это скорее месты. Не вижу возможности такое реализовать вовсе.
  • иметь возможность передать внутрь несериализуемые данные (к примеру set-ы и map-ы).

Ещё у меня был ряд сложностей с undefined-null-NaN. Кажется там всё перегонялось в JSON, и slimer поступал с ними не так, как phantom. Кто-то из ужасно коверкал данные по пути. Постепенно тесты всё больше и больше покрывались набором костылей. Часто получал ошибки вроде circular reference или что-то в таком духе, если куда-нибудь попадали несериализуемые данные.

ошибки в evalute можно так же контролировать
()=>{
try {} catch(error) { return что-то-что-подверглось_анализу}
}

Эммм, я про тесты. Когда посреди теста сломалось что-то в одном из сотен его evaluate-ов. А стектрейс в консоли содержит чёрти что, потому что упало то оно на самом деле вообще в другом процессе. Тут нужно, чтобы управляющая библиотека склеивала стек-трейсы и грамотно обрабатывала такие ошибки. Теоретически возможно, но на практике пока не встречал.

По другому используйте electron без оберток, он позволяет подгружать на страницу обычные nodejs-модули, да и возможностей контролировать ситуацию гораздо больше чем у nightmare, все таки это библиотека для тестирования, а не ботописания.
Как прикажете «дожидаться загрузки DOM» например в богомерзком личном кабинете МТС — там асинхронно загружается порядка 10 кусочков (гудки, подписки и прочая муть) страницы? Причём самая важная информация может тупо не загрузиться — пользователь должен нажать малюсенькую иконку «Обновить».
если интересует появление конкретного элемента, то достаточно сделать wait(cssSelector) и оно будет ждать его появления до таймаута, заданного при инициализации (дефолт 30 сек), если не дождется выплюнет исключение.
Если селектор есть изначально, и нужно отловить данные, можно сделать .wait(fn[, arg1, arg2,...])
Пример с тестов:
        .wait(function () {
          var text = document.querySelector('a').textContent;
          return (text === 'A');
        });

Получить наличие значения или его отсутствие можно через return !!text
К примеру, модно заинжектить свой код, в котором все ajax оборачиваются в функцию обертку (простите за тавтологию).
Да верно. Любой код, к которому нет доступа напрямую.
Спасибо, не знал про Electron. А то PhantomJS уже совсем старичок, да.
Правда с недавних пор (версия 59 для Mac и Linux, и 60 для Windows) Chrome начал нативно поддерживать headless browsing (можно найти по ключевым словам 'Getting Started with Headless Chrome'), так что есть мнение, что надо начинать больше в ту сторону смотреть…
столкнулся с одним сайтом, не буду упоминать их в суе, вдруг напрягутся. Так вот их сайт не загружается в кошмаре, висит на инициализации, не стал вникать почему, но это стало причиной попробовать хедлесс хром, и что я могу сказать, штука очень даже достойная.
Если сравнивать с кошмаром, конечно там можно прокидывать низкоуровневые запросы к девтулс хрома, но делается это через экшен кошмара + экшен электрона + вызов обсуждаемых функций.
Плюсы, которые я сразу в хеддлес хром для себя отметил, есть возможность активировать подписки эмиттеров сетевых сообщений, будь то post get запросы к бекэнду или активность на поднятых сокетах, использование авным образом всего апи девтулс.
Минусы, все манипуляции с браузером достаточно низкоуровневые, а потому если требуется что-то быстрое типа 3 кликов и забыть, кошмар явно в выигрыше, а вот если нужно что-то «извращенное», есть смысл посмотреть к хедлессу. Не исключено, что кошмар рано или поздно посмотрят на эту возможность и сделают свое высокоуровневое апи под хеддлес. Время покажет.
Sign up to leave a comment.

Articles