<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Michael Bodnarchuk @davert on Medium]]></title>
        <description><![CDATA[Stories by Michael Bodnarchuk @davert on Medium]]></description>
        <link>https://medium.com/@davert?source=rss-69fd0a60a352------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*wkRKI0Zc__NZg9eB.jpg</url>
            <title>Stories by Michael Bodnarchuk @davert on Medium</title>
            <link>https://medium.com/@davert?source=rss-69fd0a60a352------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 18 Jun 2026 20:24:57 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@davert/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Dostoevsky meets OpenSource]]></title>
            <link>https://medium.com/@davert/dostoevsky-meets-opensource-d9a7c5080050?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/d9a7c5080050</guid>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Mon, 20 Feb 2023 20:08:53 GMT</pubDate>
            <atom:updated>2023-02-20T20:08:53.375Z</atom:updated>
            <content:encoded><![CDATA[<p>Recently Denis Puskarev aka zloirock published a <a href="https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md">blogpost inside Readme of his open-source product core-js</a>. In the post, he wrote the story of his life and the burden of being an open-source maintainer.</p><p>Pushkarev’s post was related to his open-source library, core-js, but the writing style and the depth of thought he exhibited in his post reminded me of Dostoevsky’s writings. If we look wider, we can see this is not a story of a person but a common mindset built into Russian society.</p><p>As an <a href="https://threadreaderapp.com/hashtag/opensource">#opensource</a> developer I feel his pain, but as a person, I can’t understand the logic of that person.</p><p>All his life problems are direct consequences of his actions but instead of taking responsibility for them, he blames the world and greedy corporations.</p><p>His first mistake: he decided to return to Russia. Living there was his own choice. But Russia strikes back. What a surprise!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1006/0*-X1ZqfzeiDoK2zcv.jpg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/868/0*dzWUjNhuZSPC2CMW.png" /></figure><p>In his post (which replaced Readme of core-js) he begs for money while writing about how poor he is he wants a “new iPhone for his wife”, so he talks about being entitled to luxury</p><p>Also, he mentioned he has 2.5$K on donations and 10K$ on previous contracts</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Z6NbUk58Kw_UqDUe.jpg" /></figure><p>Remember the Raskolnikov from Crime and Punishment? That’s the same character. While thinking of his own greatness he suffers from a lack of money. Denis could drop core-js altogether or maintain it part-time but then he will lose his mission and his vibe as a world Savior</p><p>I would not have written that thread if he had not mentioned the war in his post.</p><p>(btw, why? As no one asked him about that, really!)</p><p>He said that <a href="https://threadreaderapp.com/hashtag/opensource">#opensource</a> is out of politics while making a political statement in the next line. It’s double thinking which was also shown in The Idiot novel</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/507/0*t1OTf7BeuHqzw2XV.png" /></figure><p>Sure, a person like him would think that he is the most victim in the world, so he has no empathy for war victims The difference here: war victims didn’t choose their destiny but Denis did.</p><p>War victims were killed, lost their homes, or lose their beloved ones but Denis didn’t</p><p>Today over 300 000 such characters are at the war in Ukraine</p><p>👿They are ‘out of politics’ but have their political opinion of two evils<br>👿They blame the West for their miserable lives<br>👿They don’t take responsibility for their actions</p><p>Maybe they are not evil by themselves. Maybe not the worst people. Who knows? They had their families but once they decided to go to kill others</p><p>The mix of messianism, victimization, and infantilism turned them into a barbarian horde terrorizing my country.</p><p>A significant part of Dostoevsky’s stories is murder and a court. In a novel written by 𝗰𝗼𝗿𝗲-𝗷𝘀 maintainer Denis Pushkarev this section is also presented.</p><p>We have a <a href="https://web.archive.org/web/20200325163526/https://kraevoy--alt.sudrf.ru/modules.php?name=sud_delo&amp;srv_num=1&amp;name_op=doc&amp;number=1733512&amp;delo_id=4&amp;new=4&amp;text_number=1">court ruling on Denis’ case</a> with some details I would like to share. So what it was about?</p><p>In 2020 Denis had an ‘accident’, as he named it.</p><p>Denis was driving a motorbike at 60 km/h In the night when he hit two young women. One of them died. He summarized it as “shit happens”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-4ag-relVWUtEZDI.jpg" /></figure><p>Denis blames the victim (they were drunk, had dark clothes, it’s russia, etc), while the court didn’t take his arguments as reasonable:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*uTMyzAAp9HUY9wva.jpg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*f7n6lM0IcUF7P_aY.jpg" /></figure><p>But did he have a chance to prevent this tragedy? According to the court — yes. The road was straight, and the observability was good, as well as the weather conditions.</p><p>Yes, it’s russia if you can be killed at a pedestrian crossing and you get blamed for that!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*-ZWJL6WLcUcuqdH_.jpg" /></figure><p>Denis states that he could not see them as they were lying on the ground. If they were standing he would see them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*bo1gqqv2yQHHkgcV.jpg" /></figure><p>A strange argument, as there could be a road hole anywhere. His lights should be able to detect something on the ground. Russian roads are not that good not to take that into account.</p><p>Denis tried to blame the victims, as <strong>the only victim in this story is himself</strong>!</p><p>That crazy drunk girl unexpectedly died causing a disturbance in core-js maintaining process!</p><p>While Denis accepts his guilt he doesn’t feel regret</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*P8AtMEG3ZDO7nvzJ.jpg" /></figure><p>Moreover, Denis blames the mother of the victim for a bad upbringing.</p><p>That sounds insane to me. Really. I don’t know what to add…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*MFuFQWkJGT3Rvf00.jpg" /></figure><p>Denis regrets the fact that he is not a privileged person and can’t escape the prosecution.</p><p>That’s how that society works. “Oh, I wish I could bribe the policemen and the court”. Those are his thoughts that he thinks are acceptable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gIv38E9Pnhdr_ac5.jpg" /></figure><p>Did you notice how he marked the victims? In quotes. Why?</p><p>Correct, <strong>he is one TRUE victim</strong> of that story.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9ncLzzCIilhmIUMW.jpg" /></figure><p>What a plot, what a character, Mr. Dostoevsky, wake up, you are missing so much here!</p><p>So instead of Crime &amp; Punishment that could be a story of Crime &amp; Bribe but because greedy corporations didn’t pay him for open source, that story didn’t happen.</p><p>But thanks to the tech community who donated to him, now he has enough money for such cases.</p><p>That was a fantastic novel.</p><p>But I must say to all people who admire Russian literature: you would prefer not to live inside their novels.</p><p>This is not fiction, though. And I’m sorry about the victims.</p><p>The final hypocrisy is Denis posting a photo of his son trying to manipulate the reader’s emotions. And asks for money. Somehow, he didn’t post a photo of a girl he killed. But she was someone’s daughter too.</p><blockquote>Yet, you donated to him and not to his victims</blockquote><p>How can Russians kill so many people in Ukraine? Why don’t they count others’ lives?</p><p>That’s why!</p><p>🤔 Don’t they have empathy?</p><p>🤮 No, it is you who must feel empathy to them</p><p>🤔 Why don’t they sympathize the victims?</p><p>🤮 Because they are the only victims here</p><p>My main point of this post was to show how those things considered to be normal in Russia are not such in modern societies. The Ukrainian community was angry with his statement about ‘two kinds of evil’. Let’s imagine he could put some racist slur into his post. Will he also be considered a good person to send money to?</p><p>Denis manipulates the community presenting himself as a self-proclaimed messiah, Internet stands on his shoulders! But in reality, he abuses the bus factor and puts the community at security risks with his behavior.</p><p>And the worst thing is that Russian society has the same paradigm. Self-centered people constantly focused on their suffering, accusing others of their miserable lives. So it’s not about Denis at all. It’s about Russian society. It’s rotten.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d9a7c5080050" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why I Don’t Enjoy Writing PHP Anymore]]></title>
            <link>https://medium.com/@davert/why-i-dont-enjoy-writing-php-anymore-aee8a85ca8aa?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/aee8a85ca8aa</guid>
            <category><![CDATA[php-development]]></category>
            <category><![CDATA[php-8]]></category>
            <category><![CDATA[php]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Tue, 04 Oct 2022 20:11:53 GMT</pubDate>
            <atom:updated>2022-10-04T20:11:53.670Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This post was started from my </em><a href="https://twitter.com/davert/status/1577365339632975896"><em>Twitter thread</em></a><em>, please follow me to join the discussion.</em></p><p>I enjoyed writing PHP in the past. It was my first web-development language and the first programming language I was paid for. It had its evolution path and even though we can’t say that PHP is stuck in the past, its current development strategy is problematic, and here is why.</p><p>I am the creator and one of the maintainers of <a href="https://codeception.com">Codeception Testing Framework</a> and <a href="https://robo.li">Robo Task Runner</a>. And I know some shit about maintaining PHP libraries.</p><p>PHP development nowadays is bumping versions, updating types, and tests, and getting out of cross-dependencies conflicts.</p><p>Let’s imagine this situation:</p><p>I have my own library <strong>MyLib</strong> that is expected to support PHP 7.4 and PHP 8+ at the same time.</p><p>Meanwhile the <strong>coollib</strong> package I depend on releases its v2 where it changes the interface of the same function to an incompatible one:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-OaYOj_k9XMA7pk3.png" /><figcaption>dependencies of MyLib and clients of MyLib</figcaption></figure><p>🤓 Client #2 already migrated PHP 8.1 and wants to install coollib 2.0 while</p><p>🤠 Client #1 is using PHP 7.4 and can’t move to coollib 2.0</p><p>As MyLib author I can either drop 🤠 Client #1 and make a major release not because I introduced some breaking changes but because I bumped dependency of coollib.</p><p>Now imagine what happens if coollib has also dependencies… And so on…</p><p>But still, I don’t understand why</p><p><em>doStuff(mixed $val)</em></p><p>and</p><p><em>doStuff($val)</em></p><p>are conflicting with each other as they are basically the same function! However, PHP engine treats them differently.</p><p>So here are two fundamental problems we have in modern PHP:</p><h4>🎃 <strong>Problem #1:</strong> All PHP classes and functions are loaded globally.</h4><h4>🎃 <strong>Problem #2:</strong> New PHP types are not backward compatible.</h4><p>If either of these won’t be a problem, we would not get into dependency hell.</p><h4>Problem #1 was solved in In #NodeJS.</h4><p>If you require a module it will stay only in the current context and won’t affect the whole application.</p><p>So in NodeJS context, different versions of the same library with different signatures of methods can live together.</p><h4>Problem #2 could be solved on PHP engine level</h4><p>However, it was not predicted from the start. Using types in the ecosystem and getting into dependency conflict was not an expected outcome of introducing more and more incompatible types into the engine.</p><p>Libraries tend to add more and more type changes with breaking compatibility in interfaces every year. Could a community solve this? Yes! Banning types could be an option and staying with PHP 7.0 features only. But that doesn’t sound cool when you know that PHP 7 is not supported anymore and you don’t actually enjoy writing legacy code. Anyway, we can’t force maintainers to keep on old interfaces, right?</p><h4>So let’s sum up:</h4><p>While PHP still keeps ugly array_* str* functions from 90s, it breaks compatibility in the ecosystem with every new release.</p><p>So it’s neither a modern language nor a stable one.</p><p><em>(sorry, </em><a href="https://threadreaderapp.com/hashtag/PHP"><em>#PHP</em></a><em>, you know I love you but I must have said this)</em></p><p>While you can think that everyone can do upgrades every year, it can be automated via Rector and so on… But you can’t run Rector on all your dependencies and bump new versions without the maintainer’s permission.</p><p><strong>So you get stuck with the lowest PHP version of any of your dependencies.</strong></p><p>That’s how some big projects are still on PHP 7.2..7.4 and can’t get to PHP 8.1.</p><p><strong>Upgrading has its cost.</strong></p><p>While making a mid-sized framework-based project can be fine to upgrade, large enterprise codebases with custom core and a dozen of dependencies are painfully hard to upgrade</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/951/0*sE9MKmS8lvEDwSgF.jpg" /></figure><p>So let’s get back to me, a library author who has a library that just works.</p><p>🤓 Client #2 (mid-size) upgraded their app and wants me to upgrade my code as well.</p><p><a href="https://emojipedia.org/cowboy-hat-face/">🤠</a> Client #1 (enterprise size) could not get an upgrade yet and wants to use MyLib.</p><p>Should I drop the enterprise client? I don’t want to. Actually, that enterprise client may be supporting MyLib with donations or paying me for consultancy.</p><p>As an author of a general-purpose library, I will need to maintain a library with versions for all currently used PHPs. You see, that sucks!</p><p>But let’s say, I decided to drop support for all old PHPs.</p><p>I say: <em>my lib is PHP 8.1+ compatible!</em></p><p>Client says: <em>ok, we are not going to use your lib, as we won’t upgrade just to use it</em></p><p>I can probably say: <em>how about upgrading to PHP 8.1, as old ones are not maintained and don’t even get security patches!</em></p><p>But the client will reply: <em>we have a team of 100 PHP developers, they are not so stupid as you might think, they also want to upgrade. But we can’t pay them for a month just to make your shitty MyLib be installed on our application.</em></p><p>And that’s the dead end. Upgrading in PHP is very expensive. And it happens for no good reasons. It happens because the PHP engine does not keep the compatibility of interfaces between releases, because PHP libraries upgrade to the most modern features, and because we share the global namespace of loaded classes. As a library maintainer, I need to balance upgrades, create bridges between different libraries and always test for compatibility with other dependencies.</p><p>But I’m tired. And I think the majority of maintainers in PHP ecosystem are tired of needless upgrades as well:</p><h3>taylor otwell 🪐 on Twitter: &quot;Agree with you that PHP breaking changes are being managed very poorly and they often have zero benefit ... / Twitter&quot;</h3><p>Agree with you that PHP breaking changes are being managed very poorly and they often have zero benefit ...</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aee8a85ca8aa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JavaScript: the Future of End to End Testing]]></title>
            <link>https://medium.com/@davert/javascript-the-future-of-end-to-end-testing-bfc00e23110b?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/bfc00e23110b</guid>
            <category><![CDATA[selenium]]></category>
            <category><![CDATA[cypress]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[protractor]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Mon, 20 Jan 2020 17:04:50 GMT</pubDate>
            <atom:updated>2020-01-24T13:16:11.493Z</atom:updated>
            <content:encoded><![CDATA[<p><em>UPDATE: A few days after this post was published a new browser automation tool emerged! </em><a href="https://github.com/microsoft/playwright"><em>Playwright</em></a><em> provides native cross-browser support without using WebDriver protocol. I added it to this post. And I must say, that JavaScript indeed is the future and the future happens today!</em></p><h3>The State of Browser Test Automation</h3><p>End to End testing used to follow a very conservative approach. Everyone was using Java/Python/Ruby with Selenium and it really felt that there is no good alternative to this setup. Selenium was everywhere and at some point, it even transformed its protocol to W3C standard. <strong>Ok, we have a W3C standard now, so why do we need alternatives?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/525/1*KvIpjHv_jUuZFCrXyr0d6g.png" /></figure><p>We always need alternatives and the tech community is great for creating ones! However, before the magnificent rise of JavaScript, no other platforms did provide any sane and popular solution. Nowadays, in the JavaScript ecosystem, we already have 3 alternatives to Selenium and a room is open for new ones! So, in my opinion, <strong>switching all browser test automation to JavaScript is a matter of time </strong>now. This is a very ambitious statement, but from business, perspective choosing faster and more stable tools over old Selenium in Java should dramatically increase the productivity and outcome for software developers in the test.</p><p>The only pain point of switching is JavaScript. Most test automation engineers are trained to work with Selenium in classical backend languages like Java and Python, and switching to a new language or tool can be a problem for them. Test automation was done in Java, all new engineers were trained from scratch for Java and Selenium, and this kept repeating, year by year.</p><h3>Javascript vs Java vs Python</h3><p>Ok, but what made JavaScript this popular and why it is winning the battle? At this moment, it’s hard to say it is winning in numbers but it wins in technology. Let me list a few points on what driven JavaScript browser testing evolution:</p><ul><li>JavaScript is already inside the browser. Obvious point. Why to learn two languages if you can use one?</li><li><a href="https://electronjs.org/">Electron</a> — a framework that allowed to wrap a browser inside JavaScript engine. It allowed creating a set of Selenium alternatives like <a href="https://github.com/segmentio/nightmare">Nightmare.js</a> and <a href="https://www.cypress.io/">Cypress.io</a></li><li><a href="https://github.com/ChromeDevTools/devtools-protocol">Chrome Dev Tools Protocol</a> — a take from Chrome Development team on bringing their own (non-W3C standard) protocol for controlling browser.</li></ul><p>I can also mention the simplicity of a language, it’s flexibility, npm, and the rise of frontend applications as additional points that boosted interest to browser testing in JS. However, unlike traditional setups (Java, Python) <strong>JavaScript was never designed for end to end testing.</strong></p><p>That’s right.</p><p>The problem here is the major feature of JavaScript — asynchrony is absolutely useless, and even dangerous when it comes to testing in a browser.</p><ul><li>All browser commands must run asynchronously (as they always need some time to finish)</li><li>Each test is a list of those commands</li><li>Each test should be linear and predictable</li></ul><p>To sum up, we need to run all the commands one by one. Otherwise, we can make tests unpredictable. For instance, if we send 2 commands to the browser: “check element” and “click” we will have no idea which commands finish first and these tests will fail for random reasons all the time. To reduce this flakiness test automation engineers should always keep in mind that all their commands to browser must be synchronized in order to make tests pass. That’s something that doesn’t exist in Java.</p><h3>Tools for Browser Testing</h3><p>And now it is time to overview all testing tools over there. Also, I will share their strengths and weaknesses and implementation concerns.</p><figure><img alt="https://cypress.io" src="https://cdn-images-1.medium.com/max/1024/1*HuEr6-Y7nXOTGJoyZf0Yew.png" /><figcaption>Cypress.io executes tests inside a browser context with automatic waits and requests mocking.</figcaption></figure><h4><a href="https://cypress.io">Cypress.io</a></h4><p>The most popular Selenium alternative nowadays is brought by a Cypress.io company. Cypress.io was built with the idea that if JavaScript is running inside a browser, we should execute our test within it as well. They built a wrapper on top of a browser using Electron and packed it as a feature full standalone solution. Cypress.io got popular as it was very simple in use, especially for frontend engineers. <strong>Working with Cypress.io is as simple as using JQuery in good old days. Cypress.io is faster than Selenium, it is more stable</strong>, and can take a benefit from running within an application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MUQu9qMsyr5AUqjS_2PurQ.png" /><figcaption>Cypress.io visual test runner brings joy to testing</figcaption></figure><p>Cypress.io is great! However, before choosing Cypress.io, consider its limitations. Because Cypress.io operates internally within a browser context it doesn’t have access to external features like:</p><ul><li>using iframes</li><li>managing tabs</li><li>managing multiple windows</li><li>uploading files</li><li>downloading files</li><li>sending native keyboard and mouse events</li></ul><p>With Cypress.io it is also hard to test interaction with 3rd party websites<br>and it has a lack of cross-browser support.</p><p>Cypress.io works great when it comes to testing single-page applications or components. Cypress.io is loved by developers! But again, the technology behind Cypress.io may not always fulfill the requirements.</p><h3>WebDriver</h3><p>When it comes to cross-browser testing, test engineers still prefer WebDriver. Yes, WebDriver is a standard and even the most sophisticated browsers, like Safari or IE are following this standard.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*NenJBQECplFa4WvwD8DQHw.jpeg" /><figcaption>The most popular Selenium WebDriver implementation in JS</figcaption></figure><p>Talking of WebDriver implementations I need to say in JavaScript we have two popular implementations:</p><ul><li><a href="https://www.protractortest.org/">Protractor</a> — which is built on top of the official Selenium library and tries to bring Java-like syntax into JS.</li><li><a href="https://webdriver.io/">webdriverio </a>— alternative JavaScript implementation.</li></ul><p>As of the beginning of 2020 Protractor is the most popular WebDriver solution, however, it has a lack of maintenance at this moment. I have deep concerns about its future <a href="https://dev.to/davert/5-reasons-you-should-not-use-protractor-in-2019-3l4b">so I wrote a post about it</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/167/1*m0h5QOSHlePD5rgAUlJAag.png" /><figcaption><a href="https://webdriver.io">webdriverio</a> is a modern WebDriver implementation</figcaption></figure><p><a href="https://webdriver.io">webdriverio</a> has a good API, great documentation, cross-browser support, native mobile apps testing support and a rich set of tools built on top of WebDriver protocol.</p><p>The technology behind WebDriver has its issues:</p><ul><li>hardened setup — Java, Selenium Server and ChromeDriver (or IEDriver, GeckoDriver) needed. Not as easy to start comparing to Cypress.io</li><li>no access to browser internals — no request mocking, network interception, access to headers, or downloads out of box.</li><li>speed — the way WebDriver operates makes it about 3 times slower comparing to all alternatives.</li><li>strictness — WebDriver is a standard, so it is very strict about what you can do inside a browser. If an element is on a page but a center of element is not visible — you are not able to click that element. If element is moving — you can’t control it.</li></ul><p>WebDriver is a great and stable solution with the biggest community. For classical stable setup, WebDriver is still the best on the market. Also, it has rich ecosystem and services like <a href="https://saucelabs.com/">SauceLabs</a> or <a href="https://www.browserstack.com/">BrowserStack</a> which help scaling WebDriver tests.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*9BG6g9a_2wGwAJVs5aAofg.png" /><figcaption><a href="https://github.com/puppeteer/puppeteer/">Puppeteer</a> is browser control tool from Google</figcaption></figure><h4><a href="https://github.com/puppeteer/puppeteer/">Puppeteer</a></h4><p><a href="https://github.com/puppeteer/puppeteer/">Puppeteer</a> is like a mix of the best from two worlds — WebDriver and Cypress.io.</p><p>Puppeteer is built on top of Chrome DevTools protocol by Chromium developers. So it is using all the API that browser can expose and that’s why it is much more powerful than classical WebDriver. If WebDriver is limited to its standard (all methods should behave similarly in all browsers), Puppeteer is focused around Chrome and Firefox only, so it can drive innovations much faster.</p><p>Unlike Cypress.io, Puppeteer gives you true external control of a browser.<strong> You can manage tabs, iframes, incognito sessions, network (mocking requests), file uploads, downloads. </strong>Almost everything! But its speed is comparable to Cypress.io, yes Puppeteer is really fast.</p><p>The only problem with Puppeteer — it is a general-purpose library, and not a test automation solution. So developers usually pair it with <a href="https://jestjs.io/">Jest</a> or <a href="https://codecept.io">CodeceptJS</a>.</p><p>To be correct I need to list the weaknesses of Puppeteer. But I don’t see any technical issues with it. It gives everything possible to you so you could write the most sophisticated browser tests. It is easy to install, has nice API, and very flexible in control. It’s a very straightforward tool, so unlike Cypress, it doesn’t give you nice features like automatic-waiting for elements, or waiting for animations. If you need those features — you need to develop them by yourself.</p><p>Puppeteer is great as a technology but has a higher learning curve than Cypress.io and less learning materials than WebDriver. It requires experienced JavaScript engineers who can set it up and build a testing framework around it.</p><h4><a href="https://github.com/microsoft/playwright">Playwright</a></h4><p>We didn’t hear any notable activity from the Puppeteer team for some time. Puppeteer 2.0 was released without any major changes and no real compatibility breaks. It seemed that Puppeteer&#39;s development entered the boring stage when only new minor improvements and bugfixes were introduced. We didn’t know that the team behind Puppeteer was working on another project which <strong>takes the best from Puppeteer but extends it to Firefox and Safari</strong>.</p><p>That’s right, officially announced on January 2020 <a href="https://github.com/microsoft/playwright">Playwright</a> already looks as a gamechanger. It has polished API from Puppeteer with all its features. Under the hood, Playwright patches Firefox and Webkit (Safari engine) to include its automation API. So this brings a very low-level and very fast protocol for browser control. This approach won’t work with any closed source browser. However, with Microsoft finally switching to Chromium we won’t need any other desktop browser to support in tests.</p><p>Playwright team also included several enhancements comparing to Puppeteer:</p><ul><li>reduce the need for timeouts</li><li>better detection for element visibility before interaction</li></ul><p>I didn’t have a chance to try it (yet) but looking forward to doing so. I expect Playwright to be highly loved by developers and test automation engineers. The idea and technology look great, as well as the team behind it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VjWsyasduivy_Hkr2LRq2A.png" /><figcaption>TestCafe is the fastest cross browser test runner</figcaption></figure><h4><a href="https://devexpress.github.io/testcafe/">TestCafe</a></h4><p>Another great technology with its own pros and cons. TestCafe does a very nice trick — instead of controlling browser on its own, it starts a proxy server that intercepts any calls in a browser and injects their script inside of them.</p><p>This is how it works: when you access google.com in a test, the browser is actually opening:</p><pre>h<a href="http://192.168.0.110:38475/xVPmF1Kwb/http://google.com/`">ttp://192.168.0.110:38475/xVPmF1Kwb/http://google.com/</a></pre><p>The real address is a proxy server that sends a request to google.com but appends its own script into every HTML received. This server also starts and closes the browser, however, it doesn’t control a browser when a test when it is running. So, as in Cypress.io, your tests actually work inside a browser (internally).</p><p>This solution makes <strong>TestCafe the fastest tool with cross-browser support on the market</strong>. Indeed, if you don’t need to control a browser, you can use any browser you want! Even Safari, even IE, even mobile Chrome! Every browser can be taken by TestCafe and this will be much faster than WebDriver (because tests are executed inside the browser). The issues with this technology are mostly edge cases which is hard to be listed. Basically, TestCafe should work for the majority of tests, but when it doesn’t work, you won’t have a clear idea why. And no debug tools to help you with that.</p><p>TestCafe has a rich set of features, it is fast and has nice community around it. You should definitely take a look at it, if cross-browser support is your primary requirement.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gW9Ap7m9DedZyRyxGwh2sA.png" /><figcaption><a href="https://codecept.io">CodeceptJS</a> allows running tests in Puppeteer, WebDriver, TestCafe</figcaption></figure><h4><a href="https://codecept.io">CodeceptJS</a></h4><p>Cypress.io, WebDriver, Puppeteer, TestCafe — they are all great. They solve the problem of testing in their own way. However, all those frameworks have their own API and their own syntax. Once we started writing tests we won’t be able to migrate to another engine when we hit an unsolvable problem.</p><ul><li>What if we started writing tests in Puppeteer but then we received a requirement to support Safari in tests?</li><li>We started with WebDriver but we need more browser control that only Puppeteer can give us?</li><li>We started in TestCafe but some tests are unstable</li><li>We started with Cypress.io but our website contains iframes or we need to run tests in two windows.</li></ul><p>So here is the idea behind <a href="https://codecept.io">CodeceptJS</a> — a meta-framework for browser test automation. CodeceptJS takes all popular browser driving engines, wraps them and provides you with a unified syntax. Unlike other tools listed in this article, <strong>CodeceptJS doesn’t control the browser on its own, it delegates the control to WebDriver, Puppeteer, or TestCafe</strong>. This allows CodeceptJS to be focused more on developers&#39; experience. For instance, <strong>it brings page objects, step retries, and interactive pause</strong> out of the box. CodeceptJS is as simple in usage as Cypress.io but allows you to use different technologies.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q7tVi7G0ztMJtII_IDtEDg.png" /><figcaption>CodeceptJS has its own <a href="https://codecept.io/ui/">graphical test runner</a></figcaption></figure><p>While Cypress.io is good for frontend engineers and matches their experience, CodeceptJS focuses more on pure end to end testing. So the test in CodeceptJS looks more like a test plan and not the JavaScript code. So even manual QAs can start working with it learning JavaScript step by step.</p><h3>Conclusion</h3><p>I believe this year will be game-changing for test automation. <a href="https://www.marketsandmarkets.com/Market-Reports/automation-testing-market-113583451.html">Test automation market is going to hit 30 billion dollars in next years</a>. And JavaScript will drive this growth and the innovation in test automation. <strong>Consider switching your browser tests to JavaScript today</strong> — but choose the tool wisely, before picking up the most popular <a href="https://cypress.io">Cypress.io</a> or <a href="https://www.protractortest.org/">Protractor</a> estimate the alternatives like <a href="https://codecept.io">CodeceptJS</a>, <a href="https://webdriver.io">webdriver.io</a> or <a href="https://devexpress.github.io/testcafe/">TestCafe</a>. They can match your requirements better.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bfc00e23110b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to show all Protractor tests without executing them]]></title>
            <link>https://medium.com/@davert/how-to-show-all-protractor-tests-without-executing-them-96dac1b7932c?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/96dac1b7932c</guid>
            <category><![CDATA[protractor]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[testing]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Thu, 26 Dec 2019 21:21:49 GMT</pubDate>
            <atom:updated>2019-12-27T00:20:42.188Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*NenJBQECplFa4WvwD8DQHw.jpeg" /><figcaption>ProtrcatorJS</figcaption></figure><p>When your project contains lots of end-2-end tests you often want to <strong>list all tests without actually executing them</strong>. This may happen because end-2-end tests can take a long time on execution. And they often require special local environment setup.</p><p>So what if you want just to see what tests exist in a project?</p><p>Use <a href="https://github.com/testomatio/check-tests#cli"><strong>check-tests</strong> CLI</a> tool which can be executed via npx without installing.<br>Execute it specifying the testing framework you use (protractor in our case) and glob pattern to match test files. That’s all!</p><pre>npx check-tests protractor &quot;specs/**.js&quot;</pre><p><em>It is important to use </em><em>“ when specifying files pattern, so wildcard patterns could be parsed correctly.</em></p><p>This will list your tests in the following format:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/694/1*14vpMuLu-MBR89ownz9mag.png" /></figure><p>If you write tests in TypeScript, that’s fine. There is built-in TypeScript support, just enable it explicitly with--typescript option:</p><pre>npx check-tests protractor &quot;specs/**.ts&quot; --typescript</pre><p>Well done! But check-tests can do much more than just listing tests. It can also be part of your testing process.</p><h4>Avoiding exclusive and skipped tests</h4><p><a href="https://github.com/testomatio/check-tests#cli"><strong>check-tests</strong></a><strong> can notify you on exclusive tests</strong> (tests within fit or fdescribe blocks), or skipped tests. When using this on CI you can fail the build when those tests detected.</p><p>Add this line before test execution into Travis CI, CircleCI, or Gitlab Runner config (format may differ):</p><pre>- npx check-tests protractor &quot;specs/**.js&quot; --no-skipped</pre><p>This way you can always ensure that no commit will introduce new skipped or exclusive tests. Good for your project. Now no one will ever fix tests by making them skipped! 😅</p><h4>Automating review process with GitHub Actions</h4><p>If your project is hosted on GitHub you can get even more with check-tests. Because <a href="https://github.com/testomatio/check-tests">check-tests is also GitHub Action</a> which can automatically review tests in your projects.</p><p>With it you can introduce the next patterns in your review process:</p><ul><li>automatically close PRs without tests</li><li>label PR with (or without) tests with a special label</li><li>automatically close PR with new skipped tests</li></ul><p>Each PR also will also contain information on added/removed/skipped tests. So you can easily check the quality of the PR.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/1*4vRYYYplmBZcciseYecOVw.png" /><figcaption>This comment is added automatically to each PR</figcaption></figure><p>Setting up <a href="https://github.com/testomatio/check-tests#installation">check tests for your GitHub project</a> can be done with editing one file. GitHub Actions are free and easy to use. Also, <a href="https://github.com/testomatio/check-tests#protractor">check the sample Protractor config</a> which will help you to start!</p><p>P.S. check-tests is part of <a href="https://testomat.io">Testomatio</a> service. <br><a href="https://testomatio.com">Testomatio</a> synchronizes your Protractor tests with test management CMS. Join our early beta to try it for your project!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96dac1b7932c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running End to End tests as Google Cloud Functions]]></title>
            <link>https://medium.com/hackernoon/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/f5e34ffc3984</guid>
            <category><![CDATA[end-to-end-testing]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[google-cloud-functions]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Mon, 27 Aug 2018 10:16:01 GMT</pubDate>
            <atom:updated>2019-04-23T09:00:19.518Z</atom:updated>
            <content:encoded><![CDATA[<p>It started all here: <a href="https://cloud.google.com/blog/products/gcp/introducing-headless-chrome-support-in-cloud-functions-and-app-engine">Google has announced support for browsers in their Cloud Functions service</a>. But well, just for one browser. Guess which one? You are right, it’s Google Chrome. A headless Chrome. Nevertheless, this announcement is huge, this can be the beginning of revolution for browser testing as we know it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XZmLA5TlzA6i01aGmGmXtQ.png" /><figcaption><a href="https://cloud.google.com/blog/products/gcp/introducing-headless-chrome-support-in-cloud-functions-and-app-engine">Announcement post</a></figcaption></figure><p>Let me elaborate. Cloud Functions in Google (similarly lambdas in AWS) are serverless stateless functions which you pay only for the time of their actual execution. Inside a testing community there was a huge interest towards using them. Indeed, we are launching our browsers just the same way — to launch and stop, and we do not want to pay for the time test is not running! Before this announcement it was pretty hard to make browsers run inside cloud functions, but now Google installs one so we are ready to try it. Can it be the game changer?</p><p>Google recommends using <a href="https://github.com/GoogleChrome/puppeteer">Puppeteer</a> library to control the browser. Puppeteer is not a testing framework by itself, so to write and run actual test we will use <a href="https://codecept.io">CodeceptJS testing framework</a>. This one can run tests in various backends, like Selenium, but also has built in support for Puppeteer. If you never met CodeceptJS before, check my <a href="https://hackernoon.com/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928">previous post: “Effective End 2 End Testing in JavaScript with CodeceptJS”</a>. And today we will try something advanced: running functional test as cloud function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/901/1*_OZPYJAdq4IuOXmG5dGC2A.png" /><figcaption><a href="https://codecept.io">CodeceptJS testing framework</a></figcaption></figure><p>At first you will need to sign up in the <a href="https://console.cloud.google.com/project/_/logs?service=cloudfunctions.googleapis.com">Google Cloud Platform</a>. Even if you don’t have an account there it’s pretty easy to create one, as everyone has Google Account. Google will ask you for a credit card but don’t worry, you will get 300$ for a year to spend, and cloud functions are included into free tier. After the account created you will need to <a href="https://cloud.google.com/sdk/docs/quickstarts">install <em>gcloud </em>command line</a> tool.</p><blockquote>Cloud Functions Free Tier includes up to 2 million invocations and 1 million seconds of free compute time per month</blockquote><p>And now let’s do some <a href="https://hackernoon.com/tagged/javascript">JavaScript</a> stuff. Let’s start by making package.json file including codeceptjs and puppeteer libraries:</p><pre>{<br>  &quot;name&quot;: &quot;browserTest&quot;,<br>  &quot;main&quot;: &quot;index.js&quot;,<br>  &quot;dependencies&quot;: {<br>    &quot;codeceptjs&quot;: &quot;^1.3.3&quot;,<br>    &quot;puppeteer&quot;: &quot;^1.6.2&quot;<br>  }<br>}</pre><p>Then run npm install . You don’t need to install any other testing framework, like Mocha, because CodeceptJS already brings one on board. It also has assertions baked-in.</p><p>Unlike in traditional <a href="https://codecept.io/quickstart/">CodeceptJS installation</a> (which still can be done), we are not able to use CodeceptJS CLI runner here as Google expects pure JavaScript function inside index.js . CodeceptJS has API for <a href="https://codecept.io/hooks/#custom-runner">creating a custom runner</a> which we will use to run our tests. Copy-paste this snippet into index.js:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/af6a97986394e995348914b8b8655acd/href">https://medium.com/media/af6a97986394e995348914b8b8655acd/href</a></iframe><p>In this setup we created configuration for Puppeteer (please note that --no-sandbox option which is required for browser to be launched in cloud) and created a basic reporter. However, we didn’t create any test yet! Tests are standalone files with *_test.js suffix which are loaded from the current directory.</p><p>So let’s create one! We will do a basic test around GitHub, that’s why I added into Puppeteer config github.com as base URL value. So a test file, named github_test.js should be pretty simple, however include some interactions and assertions. Here is the one I prepared:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ddb8eb008018069104bde62f9b94a32c/href">https://medium.com/media/ddb8eb008018069104bde62f9b94a32c/href</a></iframe><p><em>(I use </em><em>retry() for some commands as the page may not be loaded yet fully)</em></p><p>As you see, you can read the test and understand its output. The syntax is pretty simple, without needless CSS or XPath selectors.</p><p>That’s all our test. But let’s get back to our index.js and our main function which is named browserTest (that name will be used by Google). But before we deploy it to the cloud let’s try to run it locally with <a href="https://hackernoon.com/tagged/nodejs">NodeJS</a>:</p><pre>node -e &#39;require(&quot;./index&quot;).browserTest()&#39;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/742/1*pojnDYZTnQNIU4A4IzfUrg.png" /><figcaption>test is passed, the error is not related</figcaption></figure><p>If you see an output like this, the test is passing and we are ready to push it into the Cloud.</p><p>Execute this command:</p><pre>gcloud beta functions deploy browserTest --trigger-http --runtime nodejs8 --memory 1024MB</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/887/1*_qk8-XxS-38XjHA4e_EUyQ.png" /><figcaption>On first run you will be asked</figcaption></figure><p>On first run you will be asked to enable Google Cloud Functions API. You need to agree on that, and please <strong>check that billing is enabled</strong> for this project. Otherwise browser won’t be able to reach external websites.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/983/1*7AgWpBfqwAgmrPfOzp4Eng.png" /><figcaption>The expected output</figcaption></figure><p>Once the function is deployed it can be executed by the next command:</p><pre>gcloud beta functions call browserTest</pre><p>If everything is fine we should see this response after a few seconds:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/616/1*mKuN-0bKlqiF-Zwh-BVV4g.png" /></figure><p>If not — try rerunning function or look into logs, which Google also provides us with the next command:</p><pre>gcloud functions logs read</pre><p>Logs should contain tests output written step by step with assertion failures if there are any. If an error has happened it’s easy to detect where it was. For example, here how the error report will look like in logs:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AHtKgBvnoTenG2gKf0nJGw.png" /><figcaption>But I hope you will get the successfully passing test, instead of this one</figcaption></figure><p>Finally, let’s switch from the terminal to fancy Dashboard for detailed report on cloud function executions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fYVsAtuK8sRVl8m2jvbF-g.png" /></figure><h3>Summary</h3><p>The test is running and starting really fast. However, there are some limitations you need to consider before using Cloud Functions for testing. The strongest one is <strong>timeout. </strong>By default Google <strong>limits execution of cloud functions to 1 minute </strong>which can be increased to 9 minutes but no more than that.</p><p>That makes Google Cloud not yet ready for complex end to end tests with long scenarios. However, Google Cloud Functions are <strong>perfect for healthcheck tests. </strong>So you can pick the subset of your tests, and run them from time to time by Google Cloud to ensure availability of your service. If you cover the most basic functionality like login, search, etc and deploy such tests into cloud they will come in handy one day.</p><p>Other notable limitations is read-only filesystem, preinstalled Chrome, no control of the system. But the <strong>starting time is impressive</strong> and the pricing model is very interesting. I hope one day Google will consider increasing the timeout or allow us to spawn multiple functions to run our tests as Cloud Functions.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Fdde502%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Fhackernoon%2F&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href">https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f5e34ffc3984" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984">Running End to End tests as Google Cloud Functions</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Effective End 2 End Testing in JavaScript with CodeceptJS]]></title>
            <link>https://medium.com/hackernoon/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/37c8d7d6a928</guid>
            <category><![CDATA[codeceptjs]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[javascript-codeceptjs]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Wed, 16 May 2018 00:12:19 GMT</pubDate>
            <atom:updated>2019-04-23T09:00:54.269Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/901/1*_OZPYJAdq4IuOXmG5dGC2A.png" /></figure><p>There are a variety of tools in modern <a href="https://hackernoon.com/tagged/javascript">JavaScript</a> which are focused on end to end testing. However, when you need to choose one tool you can take up for a week evaluating pros and cons of different tools. You should consider their features, syntax, maintainability and in the end, you still have doubts if you are doing the right choice. Picking one library makes your tests bound to its implementation, as all end 2 end testing tools in JS have their own syntax.</p><p>Let’s say you wanted to run tests with Selenium and then you discovered that they are taking too slow and you just learned that there is a new tool Puppeteer from Google Chrome which allows driving tests faster. If you decided to migrate your tests you would need to rewrite them. What a pain!</p><p>That brings us to the first key idea of CodeceptJS.<strong> Your tests should not bound to your execution engine. Either you choose Selenium or Puppeteer your tests should look almost the same.</strong> But wait a minute… What is <a href="https://codecept.io">CodeceptJS</a>?</p><h3>Introducing CodeceptJS</h3><p>You guessed it right! CodeceptJS is a testing framework. But unlike other testing tools for JavaScript, it uses most popular JS libraries to drive your browser and adds high-level API on top of them. That’s why a test written for webdriverio could be executed in Protractor or Puppeteer.</p><p>If once you feel the limitation of one engine you can easily switch your tests to other. And what about the second key idea, high-level API?</p><p>Let’s show the code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8bc932187de72d9df01cc625cb3dd358/href">https://medium.com/media/8bc932187de72d9df01cc625cb3dd358/href</a></iframe><p>As you see, the <strong>test is very easy to read. It can even be understood by the non-technical person</strong>.</p><p>So for instance, when you need to fill in a field you can specify a name, placeholder or a label of that field and CodeceptJS will find that for you. No need of fragile and long CSS or XPath locators, if your HTML is designed correctly you can match elements by their semantic values:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cdef7ae3b9efdc31bf4ce453f4179a26/href">https://medium.com/media/cdef7ae3b9efdc31bf4ce453f4179a26/href</a></iframe><p>If you are experienced JavaScript developer you will notice something unusual in this code. There are no chained calls in the test scenarios. All actions are written one by one as a linear scenario.</p><p>Really, no promises, no async-awaits? How does it work?</p><h3>No-await?</h3><p>The problem is not about making the things work, the problem is in writing clean maintainable tests. JavaScript is very expressive language, however, maintaining codebase with dozens of then or await calls is not a simple task. Or brains are focused on handling promises and not on test scenarios themselves. That’s why CodeceptJS helps us reducing the visual noise. As the tests are linear in most cases we don’t need to know about promises and modern <a href="https://hackernoon.com/tagged/software">software</a> is smart enough to handle all promises by itself.</p><p><strong>So promises are handled by CodeceptJS, providing you with synchronous style experience</strong>. However, when you need to interrupt promise chain and get some values out of browser context you still can use async/await:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf49f529a980e1ef74759a353a64b842/href">https://medium.com/media/cf49f529a980e1ef74759a353a64b842/href</a></iframe><p>That’s the only reason why you may need async functions in CodeceptJS tests. And the only fact when you should you care about promises.</p><h3>Writing a Test</h3><p>First, we need to <a href="https://codecept.io/quickstart/">install CodeceptJS</a>. To start testing we need to choose engine (WebDriverIO, Protractor, Puppeteer, Nightmare) and specify the base URL for all tests. Let’s test something very familiar to every developer here: <a href="https://github.com">https://github.com</a>.</p><p>First test for `github.com` can start with two lines:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7dd665f7efe3ff591bf271fb62e42bf4/href">https://medium.com/media/7dd665f7efe3ff591bf271fb62e42bf4/href</a></iframe><p>I.amOnPage(‘/’); — opens a website at base url (`<a href="https://github.com`+`/`">https://github.com`+`/`</a>)<br>pause() — interrupts the execution and switches to interactive shell mode</p><h3>Interactive Shell</h3><p>In this mode, you can work with a browser side-by-side and control it with simple commands. Type `click` and choose an element to see if an element can be located that way and it can actually be clicked. If command passes — add it to your test. If not — try again with the different locator.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GstZT1nTWMGbaBc7pt48bA.png" /><figcaption>Interactive shell in action</figcaption></figure><p>So while working in Interactive Shell mode you can write down a complete test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*uwu8R-RQdMU4IRu4lrMkBQ.png" /></figure><p>Also during debug, you can put a pause() in every line and switch to interactive shell. This feature works even in headless mode. Using Interactive shell is more powerful than debugging your application with breakpoints.</p><h3>Scenario Driven Tests</h3><p>Tests are designed to be written as a scenario told by a persona, user who interacts with a system. When executing such tests with `codecept run — steps` command you will see actual step-by-step output and failures when a step fails</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*KY7YLLFQIgyRd-7Epa3bAg.png" /><figcaption>Step-by-step output when running tests</figcaption></figure><p>In a report, you will always see what step has failed and as a bonus for each failed test, a screenshot of the last page is taken so you can easily review what went wrong and fix it.</p><h3>More Testing!</h3><p>As you have seen, CodeceptJS is quite easy to start. Also, CodeceptJS is a mature framework which you can stay with. It provides native support for Page Objects, it has tools to manage data for your tests, supports testing in several browsers (multi-session testing), and because of high-level API, you can even write tests in other languages!</p><p>No. That would be JavaScript anyway. But you can write tests in other languages than English!</p><p>How about some Portuguese tests?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fb41cf4cea2c6e950e0067602958c904/href">https://medium.com/media/fb41cf4cea2c6e950e0067602958c904/href</a></iframe><p>Other translations are supported as well.</p><p>CodeceptJS can also execute mobile tests with Appium, run tests in parallel, and… Well, that goes far beyond the introductory post. So you should discover it for yourself.</p><p><strong>If you never liked end to end testing — try </strong><a href="http://codecept.io"><strong>CodeceptJS</strong></a><strong> which makes testing fun and effective.</strong></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Fdde502%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Fhackernoon%2F&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href">https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37c8d7d6a928" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928">Effective End 2 End Testing in JavaScript with CodeceptJS</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Talk: Constructing a Test Pyramid: Because your tests need architecture too!]]></title>
            <link>https://medium.com/@davert/talk-constructing-a-test-pyramid-because-your-tests-need-architecture-too-273907adb54a?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/273907adb54a</guid>
            <category><![CDATA[php]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[talks]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Sat, 23 Dec 2017 13:36:01 GMT</pubDate>
            <atom:updated>2018-07-10T09:31:12.023Z</atom:updated>
            <content:encoded><![CDATA[<p>This talk summarizes my current experience in unit/functional/integration/acceptance testing. I overviewing different levels of testing, pros and cons of their usage and focus on what makes a good test.</p><p>There are 3 qualities of a good test:</p><ul><li>Readability</li><li>Stability</li><li>Speed</li></ul><p>Make your tests readable at first so they would be easy to follow and change in future, make tests stable to codebase changes, and make them fast for better feedback!</p><p>Slides:</p><ul><li><a href="https://davertmik.github.io/slides-testing-architecture/">Slides from PhpCE</a> 2017 (Ossa, Poland)</li><li><a href="https://davertmik.github.io/longhorn-slides/">Slides from Longhorn PHP</a> (Austin, TX)</li></ul><p>Video (from PHPTour 2018):</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FWmTlen2aXYQ%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DWmTlen2aXYQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FWmTlen2aXYQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/aeab5b2647862b52dfd74b5a81e51c0c/href">https://medium.com/media/aeab5b2647862b52dfd74b5a81e51c0c/href</a></iframe><p>—</p><p>I also do <a href="http://sdclabs.com/trainings">trainings</a> and PHP testing <a href="http://sdclabs.com/codeception">consulting</a>. If you want to improve the testing culture of your team, hire developers to do test automation, contact my company <a href="http://sdclabs.com">SDCLabs</a> <a href="http://sdclabs.com/trainings">sdclabs.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=273907adb54a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Talk: Selenium Testing in PHP]]></title>
            <link>https://medium.com/@davert/talk-selenium-testing-in-php-4c924e4585d?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c924e4585d</guid>
            <category><![CDATA[php]]></category>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[talks]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[selenium]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Wed, 20 Dec 2017 13:26:02 GMT</pubDate>
            <atom:updated>2017-12-20T13:26:02.325Z</atom:updated>
            <content:encoded><![CDATA[<p>This video introduces PHP and Codeception for Testing and QA communities. PHP is not that bad, after all, and it can be used for testing web applications! Even non developer can start writing automated tests if they know basics of PHP and they use Codeception!</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FDOK_lFbgMs4%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DDOK_lFbgMs4&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FDOK_lFbgMs4%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/35414ac93f716a5789d51a6d0490d57c/href">https://medium.com/media/35414ac93f716a5789d51a6d0490d57c/href</a></iframe><p>Slides:</p><ul><li><a href="https://davertmik.github.io/selenium-php-codeception/">Slides from TestCon 2017</a> (Vilnius, Lithuania)</li></ul><p>—</p><p>I also do <a href="http://sdclabs.com/trainings">trainings</a> and PHP testing <a href="http://sdclabs.com/codeception">consulting</a>. If you want to improve the testing culture of your team, hire developers to do test automation, contact my company <a href="http://sdclabs.com">SDCLabs</a> <a href="http://sdclabs.com/trainings">sdclabs.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c924e4585d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Talk: Modern Testing with Codeception]]></title>
            <link>https://medium.com/@davert/talk-modern-testing-with-codeception-7943b1c12dcf?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/7943b1c12dcf</guid>
            <category><![CDATA[php]]></category>
            <category><![CDATA[codeception]]></category>
            <category><![CDATA[testing]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Sun, 17 Dec 2017 12:19:41 GMT</pubDate>
            <atom:updated>2017-12-17T12:19:41.897Z</atom:updated>
            <content:encoded><![CDATA[<p>This is an introductory talk to Codeception, with an overview of its most significant features. I know, the docs are long and boring so let me tell you them in 30 minutes highlighting the most important features!</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F189755954&amp;dntp=1&amp;url=https%3A%2F%2Fvimeo.com%2F189755954&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F600184908_1280.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1080" frameborder="0" scrolling="no"><a href="https://medium.com/media/fae9ef7fef84cd056c0bfcf0c17d3f16/href">https://medium.com/media/fae9ef7fef84cd056c0bfcf0c17d3f16/href</a></iframe><p>My slides are avaiable</p><ul><li><a href="https://davertmik.github.io/slides-modern-testing-phpce/#/">Slides from PHPCE 2017</a> (Ossa, Poland)</li><li><a href="https://davertmik.github.io/slides-bgphp/">Slides from Bulgaria PHP</a> 2016 (Sofia, Bulgaria)</li></ul><p>—</p><p>I also do <a href="http://sdclabs.com/trainings">trainings</a> and PHP testing <a href="http://sdclabs.com/codeception">consulting</a>. If you want to integrate Codeception testing framework into your application, and use full powers of it, contact my company <a href="http://sdclabs.com">SDCLabs</a> <a href="http://sdclabs.com/trainings">sdclabs.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7943b1c12dcf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Talk: Beyond Testing]]></title>
            <link>https://medium.com/@davert/talk-beyond-testing-fd5c97af4934?source=rss-69fd0a60a352------2</link>
            <guid isPermaLink="false">https://medium.com/p/fd5c97af4934</guid>
            <category><![CDATA[codeception]]></category>
            <category><![CDATA[php]]></category>
            <category><![CDATA[testing]]></category>
            <dc:creator><![CDATA[Michael Bodnarchuk @davert]]></dc:creator>
            <pubDate>Sun, 17 Dec 2017 11:55:41 GMT</pubDate>
            <atom:updated>2017-12-17T12:07:59.967Z</atom:updated>
            <content:encoded><![CDATA[<p>Last few years I did a series of talks titled “Beyond Testing”. They all have some minor differences depending on audience’s interest.</p><p>This talk should have been called “Beyond Unit Testing” as the main purpose of it to show that we need to think about Web Interface tests, REST API tests, developing tests infrastructure and more. The complete overview of tools and approaches available in PHP is listed.</p><p>This talk was presented at PHPSerbia 2017:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F9vjykb1h3k0%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D9vjykb1h3k0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F9vjykb1h3k0%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/fd82afcfc2fce92b638935d7bffe62e4/href">https://medium.com/media/fd82afcfc2fce92b638935d7bffe62e4/href</a></iframe><p><a href="https://docs.google.com/presentation/d/1kIs0scvRVo-Dm6MQnyZar9E0Y272jUqRWBmiNZb0YzA/edit#slide=id.p3">Beyond Testing PHPSerbia</a></p><p>There are some alternative editions of this talk:</p><ul><li>MageConf 2017 (Kyiv, Ukraine)</li><li>DutchPHP 2016 (Amsterdam, Netherlands)</li><li>J&amp;Beyond 2016 (Barcelona, Spain)</li><li>ScotlandPHP 2016 (Edinburgh, UK)</li></ul><ul><li><a href="https://docs.google.com/presentation/d/1GmFB3J2UtwNIRnSkVly9-2rqakqINJkfXq4uzALM_9s/edit?usp=sharing">Beyond Testing MageConf</a></li><li><a href="https://docs.google.com/presentation/d/1Gbe4PKJ03HdYfETyrMx8E15K1ZLLcAecXuQsCCuPjdE/edit?usp=sharing">Beyond Testing Dutch PHP</a></li><li><a href="https://docs.google.com/presentation/d/13ZAXyugEtCxKzL20K0PzAUmQc58zKLqaAjgSbroahU8/edit?usp=sharing">Beyond Testing J&amp;B</a></li><li><a href="https://docs.google.com/presentation/d/1dZEyflAbuHXmMsELHdthJXtsDdPhPUucfRmQQsBI40k/edit?usp=sharing">Beyond Testing ScotlandPHP</a></li></ul><p>—</p><p>I also do <a href="http://sdclabs.com/trainings">trainings</a> and PHP testing <a href="http://sdclabs.com/codeception">consulting</a>. If you want to improve the testing culture of your team, hire developers to do test automation, contact my company <a href="http://sdclabs.com">SDCLabs</a> <a href="http://sdclabs.com/trainings">sdclabs.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fd5c97af4934" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>