Search
Write a publication
Pull to refresh
5
0
Владислав @ihost

Программист

Send message

Забавно, что приведенный Вами код с точностью до синтаксиса вообще не создает объект, а декларирует прототип функции в лексическом scope (См. https://en.wikipedia.org/wiki/Most_vexing_parse#Example_with_classes или вживую тут https://ideone.com/J3Y0oN )


Но в целом понятно, что Вы имели в вид

А теперь тоже самое для статичных (выделяемых в стеке) фукнций.

Имеются в виду функции, использующие переменные из activation object, то бишь замыкания? Они такие же объекты с похожим жизненным циклом, так что отлавливать и подсчитывать ссылки на объекты из activation object проблем нет.


Еще раз — потенцаильная сложность это функции из host object, типа DOM-модели, но это тоже обходится в transpile-фазе


но компилятор… все еще ждем

Это вопрос к автору статьи, к которому я никакого отношения не имею. Это лишь ответ на вопрос о том, что при должной сноровке поддерживать деструкторы в ES262 не представляется проблемой

На платформе node.js решается очень легко — https://www.npmjs.com/package/weak и подобное


Для клиентской стороны немного сложнее, потребуется babel-плагин, осуществляющий обертку объектных сущностей — вроде таких https://www.npmjs.com/package/babel-plugin-source-wrapper или https://gist.github.com/IhostVlad/9310188edbdbc9f62dc3107417cc8fe4


Основная сложность в том, что придется обернуть взаимодействие с native и host-object-функциями, которые также могут хранить внутри себя ссылку на объекты — да, это объемная работа, но вполне реализуемая.


К тому же, большинство обертки и преобразования для DOM-модели уже решено здесь: https://github.com/DevExpress/testcafe-hammerhead/tree/master/src/processing

Сама по себе идея разрабатывать части web-приложения на C/C++ далеко не новая — другое дело, какой результат вы хотите получить от такого подхода? Возможно, вам будет интересно ознакомиться с WASM: http://webassembly.org/docs/c-and-c++/

Да, без качественных автоматических функциональных тестов хорошее сложное web-приложение не сделать.
Однако у оригинального Selenuim-а два недостатка: отличие языка тестов от языка клиентского кода и необходимость наличия webdriver-а для целевого браузера. И если первый недостаток давно решен в библиотеках Webdriver.io, Nightwatch, и тому подобное, позволяя писать на том же ECMA-262 ver 6+, то со вторым недостатком никаких подвижек нет.
В частности, учитывая обилие устройств, как проверить работоспособность на всевозможных смартфонах, Smart TV и тому подобное. В этом плане TestCafe нет равных, или связке TestCafe + SauceLabs — на случай если у вас нет фермы живых устройств для прогона тестов

Да, наверное можно получше сформулировать. Форма и значения в том или ином объекте могут стать известны только в runtime-фазе, например, когда прочли request body в HTTP-запросе и инстанцировали из него объект посредством JSON.parse — по сути преобразование из произвольного string в произвольный plain object.


Каждое из полей может быть null, undefined или чем угодно, но эта станет известно только в фазе выполнения. Есть такая штука как tcomb — это да, может помочь.


Опять-таки самая ближайшая аналогия из строго-типизированного языка, C#, это по типу:


dynamic excel = Interop.create("Excel.Workbook");
dynamic book = excel.Workbook[0];
book.Activate();

Одно из самых распространенных заблуждений состоит в том, что статическая типазация, или новомодные обертки для ее эмуляции в виде ES-Flow, могут помочь побороть ошибку undefined is not a function, но на деле это невозможно сделать в статическом анализе.


Аналогичный примерчик на C#. В общем-то проблема в Nullable объектах, а не то, что часто принято приводить в качестве аргумента


// One
MyClass obj = null;
obj.someMethod();

// Two
delegate void SomeFunc(int x);
SomeFunc dlg = cond ? obj.someMethod : null
dlg(10);

Теоретически можно заимплементить плагин для prettier-а, но это решает очень узкую задачу — выявление опечаток в именах подключаемых модулей, заданных в виде строковых констант. А если require(vasya${petya}) ?


Многие остальные вещи становятся известными только в runtime-фазе, так что ни EsLint, ни Flow тут не помощники. Поэтому если уж заморачиваться, то нужна более тяжелая артиллерия.


И еще раз важная заметочка: подобная задача вполне имеет место в динамическом анализе кода и функциональном тестировании. Есть как минимум:



Задачи ооочень нетривиальные в общем случае. К примеру, довольно проблемно перехватить сгенерированный script-блок из DOM-манипуляций, чтобы выполнить предварительную обертку.

почему в JS нельзя получить напрямую доступ к контексту выполнения

Раньше можно было даже программно доступ получить через parent, потом убрали видимо из соображений чистого кода и безопасности/sandboxing-а. Можно почитать тут подробнее: http://whereswalden.com/2010/05/07/spidermonkey-change-du-jour-the-special-__parent__-property-has-been-removed/


Сейчас доступ только из отладчика по скрытому свойству [[Scope]]. Подозреваю, что для node.js можно и сейчас получить доступ через V8 natives: https://www.npmjs.com/package/v8-natives, только надо с флажком будет запускать процесс


Правда, все ошибки перехватить всё равно не удастся

Если перехватить сами вызовы, которые могут генерировать новый код динамически тем или иным образом, начиная от new Function и заканчивая манипуляциями с DOM Node и создания новых script-секций, то вполне возможно
Подобная техника, правда не для шутки, а функционального тестирования, применяется в TestCafe: https://github.com/DevExpress/testcafe-hammerhead

Очень неплохо! Правда есть и недостатки, например имена лексических переменных с очепятками никак не перехватываются, да и синтактические ошибки по-прежнему актуальны. Так что нужно сделать babel-плагин, который будет выполнять пред-обработку и учитывать опечатки во всех сущностях.

Virtual DOM в React является медленным и неточным

В движке Fiber проблема производительности уже неактуальна


React требует сложного асинхронного программирования при общении с сервером

Напротив, в связке с Redux весь код бизнес-логики на клиенте может быть сведен в единое место, представляемое одним или несколькими комбинированными reducer-ами. Продолжительные по времени действия легко описать в sagas, а еще лучше реализовать всю архитектуру через events — в таком случае явные асинхронные вызовы вообще не нужны


Даже используя propType React сможет найти ошибки только во время работы программы, а не во время компиляции.

Если нужна статическая проверка, можно использовать Flow


Поддерживает ли Binding.scala серверный rendering?

И второй вопрос – а эта штука поможет в этом?

Да, с принципом работы TestCafe, Вы можете хоть с утюга запускать функциональные тесты, если там есть браузер с поддержкой ES-262 и выходом в интернет

асинхронный node.js и бороться с ним с помощью await'ов

А причем здесь, собственно, node.js? Это же клиентский EcmaScript-код, который с версии ES2017 вообще будет поддерживать это нативно. Ваше web-приложение асинхронно само по себе, а это инструмент для организации цепочки действий


общий уровень "велосипедизма".… повсеместно используемых setUp/tearDown, тут beforeEach/afterEach

В современном web-е это принятая терминология, смотрите Ava, Jest, Mocha и так далее.


Короче, что люди не делают, только бы не брать selenium

Короче, что люди не делают, только бы не разрабатывать на C++; придумали всякие интерпретаторы, динамические типизации и другие синтаксические сахара.

Под капотом, вероятнее всего, всё тот же вебдрайвер

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


Если смириться с JS синтаксисом

Выбор языка это конечно вкусовщина, но исторически сложилось, что все современные браузеры работают на ES-262, а реализовывать функциональный тест на том же языке, что и тестируемое приложение — IMHO довольно удобно

Весь вопрос в том, какую технологию вы используете на серверной части разрабатываемого/поддерживаемого web-приложения. Если node.js, то очевидно в случае TestCafe не надо устанавливать еще один инструмент, если JSP или что-то подобное, то выбор в сторону семейства Selenuim (Webdriver, nightwatch, etc).
Если PHP, Perl, Ruby или что-то еще, то вопрос с такой стороны рассмотрения открытый, но ES6/7 это все-таки тот язык, который исполняется в браузере, и писать функциональный тест писать на нем IMHO значительно удобнее, чем на Java.

Безусловно, описанная в статье ситуация с XHTML довольно проблематичная, но скорее в идеологическом плане, поскольку технически те или иные задачи все-таки можно решить. Дело в том, что исторически направления XHTML и CSS selectors развивались параллельно, о чем как минимум свидетельствует наличие двух конкурентных языков для выбора элементов документа — XPath и CSS selector, при этом оба успешно применяются в сфере автоматизации web-приложений и функциональном тестировании, в том же Nightwatch-е к примеру.
Далее по техническим вопросам. Во-первых, навигацию по XHTML лучше реализовывать посредством XPath, который изначально как раз предназначен для XML-документов, и поддерживается посредством функции document.evaluate(), по крайней мере в браузерах, приведенных автором статьи в последней таблице. Для IE старых версий тоже нет проблем, можно использовать объект new ActiveXObject("Msxml2.DOMDocument"), за-map-енный на текущее DOM-дерево, пример решения можно взять здесь https://sourceforge.net/projects/html-xpath/
Это имеет свой смысл, поскольку в общем случае CSS и уж тем более CSS selectors являются чужеродными для произвольных XML-элементов, которые не обязаны ни поддерживать стили, ни иметь какой-то внешний вид для отображения — который должен по-хорошему определяться через XSLT-преобразование (Или, если интересует поддержка IE старых версий, через Element Behaviors, во времена которых как раз задумывался XHTML с определением пользовательского поведения элементов — https://msdn.microsoft.com/en-us/library/ms531426(v=vs.85).aspx).
Во-вторых, с учетом современных тенденций в web-приложениях, включающую предварительное преобразование исходного кода в связке webpack + babel, можно сделать свою реализацию для resolve-а и transform-а исходного XHTML-кода, по аналогии с тем же JSX, который в итоге преобразования будет предоставлять набор элементов с некоторыми идентификаторами и классами, а исходный код будет выглядеть так, как задумал автор — с пространствами имен XHTML.
Резюмируя по исходной задаче, решения можно добиться без polyfills, правда потребуется две версии dist-клиентского сценария — для современных браузеров через document.evaluate(), и если захотите поддержку IE старых версий — то через Element Behaviors API, которое кстати поддерживает о-о-о-очень широкую функциональность.

К тому же под Nightwatch есть очень и очень много разнообразных примочек и фишек

Для TestCafe вы просто пишите ES6-код, и можете использовать множество различных библиотек в import-е под свои надобности, причем в selenium-е какие-то сторонние вещи интегрировать в код теста придется через эту функцию, то в TestCafe это обычный код — в таком смысле, возможности по интеграции куда шире.


Асинхронные комманды выполняются с помощью функции .executeAsync()

Безусловно! Однако этот функционал предоставляет значительно большие возможности. Да и promise / async-based стиль выглядит более читаемым, хотя наверное это уже дело вкуса.

В обоих фреймворках есть довольно легкие в использовании и в то же время конфигурируемые инструменты для ожидания наличия/отсутствия/видимости/невидимости заданного DOM-элемента, в Nightwatch эта функция и ей подобные, в TestCafe есть более богатый набор, и вообще можно использовать кастомный селектор, проверяющий сложное условие — к примеру, наличие заданных relative-элементов и другой программной логики, которую можно написать в клиентском JS-коде
Насчет iframe-ов, есть иснтументы для переключения активного контекста окна, это есть и в Nightwatch, и TestCafe ( Здесь и здесь )

@Ayzatqa, спасибо! Насчет вопроса — имеется в виду <input type="file" />? Если да, то в TestCafe для этого есть уже готовое решение, оно проверено работает
Для nightwatchjsЮ во всей видимости, можно реализовать через конструкцию .setValue('input#fileUpload', require('path').resolve(__dirname + '/testfile.txt')), как предлагают здесь, но работоспособность решения гарантировать не могу

Information

Rating
6,913-th
Location
Тула, Тульская обл., Россия
Date of birth
Registered
Activity