<?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 Túlio Bandeira Luz on Medium]]></title>
        <description><![CDATA[Stories by Túlio Bandeira Luz on Medium]]></description>
        <link>https://medium.com/@tuliobluz?source=rss-6a68c08261a1------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Nbz02r4WxZf1VoIK1UpZIw.jpeg</url>
            <title>Stories by Túlio Bandeira Luz on Medium</title>
            <link>https://medium.com/@tuliobluz?source=rss-6a68c08261a1------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 13:26:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@tuliobluz/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[Zalenium — Brief Introduction with Protractor]]></title>
            <link>https://medium.com/@tuliobluz/zalenium-brief-introduction-with-protractor-5d9e4f5f85cb?source=rss-6a68c08261a1------2</link>
            <guid isPermaLink="false">https://medium.com/p/5d9e4f5f85cb</guid>
            <category><![CDATA[zalando]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[selenium]]></category>
            <category><![CDATA[protractor]]></category>
            <category><![CDATA[zalenium]]></category>
            <dc:creator><![CDATA[Túlio Bandeira Luz]]></dc:creator>
            <pubDate>Mon, 19 Nov 2018 19:54:59 GMT</pubDate>
            <atom:updated>2022-12-19T15:34:09.287Z</atom:updated>
            <content:encoded><![CDATA[<h3>ARCHIVED Zalenium — Brief Introduction with Protractor</h3><h4>A flexible and scalable container based Selenium Grid using with Protractor</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p2V2kYlMN61auv1OmjRahw.png" /><figcaption><a href="https://opensource.zalando.com/zalenium/">https://opensource.zalando.com/zalenium/</a></figcaption></figure><p>I will bring a brief introduction about Zalenium and my experience with it, how I used with <strong>Protractor</strong>.</p><h3>About Zalenium</h3><p>Start a <a href="https://www.seleniumhq.org/docs/07_selenium_grid.jsp">Selenium Grid</a> in seconds, a grid that scales up and down dynamically with this solution based on <a href="https://github.com/elgalu/docker-selenium">docker-selenium</a> to run your tests in Firefox and Chrome. If you need a different browser, Zalenium can redirect your tests to a cloud testing provider (<a href="https://saucelabs.com/">Sauce Labs</a>, <a href="https://www.browserstack.com/">BrowserStack</a>, <a href="https://testingbot.com/">TestingBot</a>).</p><p>Zalenium works out of the box in <a href="https://opensource.zalando.com/zalenium/#docker">Docker</a> and <a href="https://opensource.zalando.com/zalenium/#kubernetes">Kubernetes</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v-afYi98_BdQGdz6O_TOAA.gif" /><figcaption><a href="https://opensource.zalando.com/zalenium/#usage">https://opensource.zalando.com/zalenium/#usage</a></figcaption></figure><p>Zalenium works conceptually in a simple way:</p><ol><li>A Selenium Hub starts and listens on port 4444.</li><li>One custom node for <a href="https://github.com/elgalu/docker-selenium">docker-selenium</a></li><li>If a cloud testing integration is enabled, a cloud proxy node to support a cloud provider (<a href="https://saucelabs.com/">Sauce Labs</a>, <a href="https://www.browserstack.com/">BrowserStack</a>,<a href="https://testingbot.com/">TestingBot</a>) will register to the grid.</li><li>A test request is received by the hub and the requested capabilities are verified against each one of the nodes.</li><li>If <a href="https://github.com/elgalu/docker-selenium">docker-selenium</a> can fulfill the requested capabilities, a docker container is created on the run, and the test request is sent back to the hub while the new node registers.</li><li>The hub acknowledges the new node and routes the test request with to it.</li><li>The test is executed and the container is disposed after test completion.</li><li>If <a href="https://github.com/elgalu/docker-selenium">docker-selenium</a> cannot fulfill the requested capabilities, it will processed by one of the enabled cloud testing platforms.</li></ol><h3>Why?</h3><ul><li>Have a stable grid to run UI tests with Selenium</li><li>Maintain it over time (keep up with new browser, Selenium and drivers versions)</li><li>Provide capabilities to cover all browsers and platforms</li></ul><p><strong>Zalenium’s main goal is: to allow anyone to have a disposable and flexible Selenium Grid infrastructure.</strong></p><p>Check the <a href="https://opensource.zalando.com/zalenium/#usage">Documentation</a>.</p><h3>Set up</h3><h4>Prerequisites</h4><ul><li>Docker version &gt;= 1.11.1 (probably works with earlier versions, not tested yet).</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dba05d9994111a8d5a65b5c54b5692ad/href">https://medium.com/media/dba05d9994111a8d5a65b5c54b5692ad/href</a></iframe><p>I&#39;m running the Zalenium with Protractor, if you don&#39;t know about it, check my post:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FrFBQzTgEqigG4%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FrFBQzTgEqigG4%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FrFBQzTgEqigG4%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="326" frameborder="0" scrolling="no"><a href="https://medium.com/media/33a7fe8db4e0e7cae52aceb78112af78/href">https://medium.com/media/33a7fe8db4e0e7cae52aceb78112af78/href</a></iframe><h4><a href="https://medium.com/@tuliobluz/automa%C3%A7%C3%A3o-com-protractor-pageobject-e-cucumber-122537179ab7">Automation with Protractor, PageObject and, Cucumber</a></h4><h3>How I used the Zalenium?</h3><p>I used with docker-compose, but what is <a href="https://docs.docker.com/compose/">docker-compose</a>?</p><p>Compose is a tool for defining and running multi-container Docker applications.</p><blockquote><strong><em>docker-compose.yml</em></strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c6380f96c457e79416a47ccaa57c0a30/href">https://medium.com/media/c6380f96c457e79416a47ccaa57c0a30/href</a></iframe><pre># To run the compose<br><strong>docker-compose up --force-recreate</strong></pre><pre># To stop the compose<br><strong>docker-compose stop</strong></pre><p>Below I will explain some important points on this docker-compose:</p><h4>The <a href="https://docs.docker.com/glossary/?term=volume">volumes</a>:</h4><pre>volumes:          <br>  - /Users/tluz/Desktop/videos:/home/seluser/videos          <br>  - /var/run/docker.sock:/var/run/docker.sock          <br>  - /Users/tluz/Documents/protractor-zalenium/.htpasswd:/home/seluser/.htpasswd</pre><blockquote><strong>/Users/tluz/Desktop/videos:/home/seluser/videos</strong></blockquote><p>When the compose runs, I&#39;m telling to share the folder on container <strong>/home/seluser/videos </strong>with my folder in <strong>/Users/tluz/Desktop/videos, </strong>then<strong> </strong>the videos generated in the container it will be copied to my folder.</p><blockquote><strong>/Users/tluz/Documents/protractor-zalenium/.htpasswd:/home/seluser/.htpasswd</strong></blockquote><p>Enabling basic auth</p><p>Providing a file with user(s) and password(s)To create a file with that information, please follow the steps for “Creating a Password File” <a href="https://www.nginx.com/resources/admin-guide/restricting-access-auth-basic/"><strong>described in the Nginx documentation</strong>.</a> After that, map the created file to the container when you start Zalenium.</p><p>In this volume, I&#39;m sharing the file .<strong>htpasswd</strong> to the container with my credentials to log in on the Zalenium stuff(Live and Dashboard).</p><p><strong>The commands:</strong></p><p>This it was the parameters that I used to my requirements.</p><pre>command: &gt;          <br>  start --desiredContainers 2                <br>        --maxDockerSeleniumContainers 8<br>        --screenWidth 1360 <br>        --screenHeight 1024                <br>        --timeZone &quot;America/Sao_Paulo&quot;<br>        --videoRecordingEnabled true<br>        --keepOnlyFailedTests true</pre><blockquote><strong><em>desiredContainers:</em></strong><em> Number of nodes/containers created on startup.</em></blockquote><blockquote><strong><em>maxDockerSeleniumContainers:</em></strong><em> Maximum number of docker-selenium containers running at the same time.</em></blockquote><blockquote><strong><em>screenWidth:</em></strong><em> Sets the screen width.</em><strong><em> screenHeight: </em></strong><em>Sets the screen height.</em></blockquote><blockquote><strong><em>timeZone:</em></strong><em> Sets the time zone in the containers.</em></blockquote><blockquote><strong><em>videoRecordingEnabled:</em></strong><em> Sets if video is recorded in every test.</em></blockquote><blockquote><strong>keepOnlyFailedTests: </strong>Keeps only failed tests on the dashboard (you need to send a cookie with the test result).</blockquote><p>In my scenario, I just needed to record the failed tests, to avoid the over storage on the machine responsible to the Zalenium and I’m gonna explain my approach to use with Protractor.</p><p>If you need more configuration Parameters you can check on the <a href="https://opensource.zalando.com/zalenium/#usage">Documentation</a> about Zalenium.</p><h4>My config file</h4><blockquote><strong>protractor.conf.js</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/001412181369922a35776e5424e884da/href">https://medium.com/media/001412181369922a35776e5424e884da/href</a></iframe><ul><li><strong>Line</strong> <strong>1</strong> I’m setting the address from the container(default: &#39;http://localhost:4444/wd/hub&#39;), but I set the basic auth and I needed to send the parameter of the user that I set on file .<strong>htpasswd,</strong> because of that my address has the parameter &#39;<strong>user2:1234@</strong>&#39;(user:password).</li><li><strong>Lines</strong> <strong>9</strong> to <strong>18 </strong>I&#39;m using multiCapabilities, when the test will run it will run with the Firefox(<strong>line 11</strong>) and Chrome(<strong>line 15</strong>), the <strong>lines 12 and 16</strong> I&#39;m setting the name from the test for every browser to in the dashboard.</li></ul><h4>Keep Only Failed Tests TRUE</h4><p>As I using this parameter I have to save the result of the tests in the browser cookies on the variable &#39;<strong>zaleniumTestPassed</strong>&#39;, let&#39;s take a look on the After(lines 37 to 39) in my test file.</p><blockquote><strong><em>spec</em>.spec.js</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9e15314ef5829c1864739053ba6fc0db/href">https://medium.com/media/9e15314ef5829c1864739053ba6fc0db/href</a></iframe><p>Description of the parameter <strong>keepOnlyFailedTests:</strong> Keeps only failed tests on the dashboard <strong>(you need to send a cookie with the test result)</strong>.</p><p>In the <strong>After</strong> <strong>(line 37 to 39)</strong> I implemented the line responsible to added on the browser cookies the variable <strong>zaleniumTestPassed</strong> with the status in the value, every time the test run the <strong>After</strong> it will be called, and if the value is false, the variable <strong>zaleniumTestPassed</strong> it will be added with the result.</p><h3>Let&#39;s try</h3><h4>Starting Zalenium</h4><p>Starting with Docker-compose run the command below:</p><pre>docker-compose up --force-recreate</pre><p>After the run the docker-compose you should see something like that:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YjULygIqbbIbsM-3EeomjA.png" /></figure><p>Run tests in this repository:</p><p><a href="https://github.com/tuliobluz/protractor-zalenium">tuliobluz/protractor-zalenium</a></p><p>In my project, I have three scenarios for my tests, two successful scenarios and one forced to fail.</p><p>When I run my tests, you can watch the tests running in real time:</p><p><a href="http://localhost:4444/grid/admin/live">http://localhost:4444/grid/admin/live</a></p><blockquote><em>If you use the basic auth, you have to log in with the user that you setting up before.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VCsMlXU4-vgKKSu5bGNghA.png" /></figure><p>When the running finished the terminal will show this log:</p><p>Chrome:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7oPHnpKznC5UCADtolSh3A.png" /></figure><p>Firefox:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_jfIlBs97iEjmk3eAMf_kw.png" /></figure><p>Like I was waiting just one scenario failed, and below has my dashboard with the scenario recorded in both browsers, let&#39;s check it out the dashboard.</p><p><strong>Dashboard:</strong></p><p><a href="http://localhost:4444/grid/admin/live">http://localhost:4444/grid/admin/live</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tc-OdVP3VA3WvDODNX2J3w.png" /></figure><p>1- List of the test were running.</p><p>2 - Test name</p><p>3 - Information about test(you can get the information about the build was running when the test broken and set in this field)</p><p>4 - You can check the logs about from Selenium and Browser Driver Log.</p><p>5 - <strong>Cleanup</strong>: The dashboard has a retention period(default 3 days), when you want to clean every test after 3 days just use the clean up. <strong>Reset:</strong> It will remove all information about the dashboard.</p><h3>Conclusion</h3><p>Zalenium bring a good feedback about my tests, I can watch the running in real time, besides the zalenium record the failed test(or every status from the tests). The dashboard gives me a way to check what is wrong in my test, as opposed to a running in headless.</p><p>Now you can check the best way to implement on your pipeline, and how you will use this tools to deliver more quality to your team.</p><p>Thank you guys!!!</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F2XtEQpM97Lvhe%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F2XtEQpM97Lvhe%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2F2XtEQpM97Lvhe%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="326" frameborder="0" scrolling="no"><a href="https://medium.com/media/57c8b0ae5b8c1855cf85ee389398a386/href">https://medium.com/media/57c8b0ae5b8c1855cf85ee389398a386/href</a></iframe><h3><strong>Reference:</strong></h3><ul><li><a href="https://opensource.zalando.com/zalenium/">Zalenium - A flexible and scalable Selenium Grid.</a></li><li><a href="https://github.com/zalando/zalenium">zalando/zalenium</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5d9e4f5f85cb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Protractor — Session ID is null. Using WebDriver after calling quit()?]]></title>
            <link>https://medium.com/@tuliobluz/protractor-session-id-is-null-using-webdriver-after-calling-quit-a461b1bf2e55?source=rss-6a68c08261a1------2</link>
            <guid isPermaLink="false">https://medium.com/p/a461b1bf2e55</guid>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[page-object]]></category>
            <category><![CDATA[protractor]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Túlio Bandeira Luz]]></dc:creator>
            <pubDate>Fri, 10 Aug 2018 16:07:09 GMT</pubDate>
            <atom:updated>2018-08-17T11:46:55.682Z</atom:updated>
            <content:encoded><![CDATA[<h4>It will help you when using the tag restartBrowserBetweenTests</h4><h3><strong>The problem:</strong></h3><p>I was suffering with a problem when I was running the tests in Protactor, in my structure containing pageobejct and cucumber. But the problem was that I using the tag <strong>“restartBrowserBetweenTests: true”</strong> on <em>protractor.conf.js</em>. When you had using this, the browser will be restarted every time that it will run and it lost the reference with test files, then it couldn’t interact with the page.</p><p>Just to <strong>remember</strong> you, if you use the tag <strong>“restartBrowserBetweenTests: true ”</strong>, this will cause your tests to slow down drastically.</p><p>The error:</p><pre><strong>org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?</strong></pre><h3><strong>The solution:</strong></h3><p>To solve this problem you have to do one function in an object to initialize the locators, that function must be called always you will run the test.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bbb1dfc3df08d147ad02c56ed79e6209/href">https://medium.com/media/bbb1dfc3df08d147ad02c56ed79e6209/href</a></iframe><p>I created the module exports to object, this object has an one arrow function to initialize<strong>(lines 5~9) </strong>the locators to be used on the test.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0431e60120b194f68a58306ce765a334/href">https://medium.com/media/0431e60120b194f68a58306ce765a334/href</a></iframe><p>Inside the Before(<strong>lines 8~10</strong>) I put the specPage.init(), this will call the initialize always the test will run.</p><p>That&#39;s works for me, thanks to read my post.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FoIY2ItAtPEdwY%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FoIY2ItAtPEdwY%2Fgiphy.gif&amp;image=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FoIY2ItAtPEdwY%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="244" frameborder="0" scrolling="no"><a href="https://medium.com/media/5bedaab0e0fec378ebf00a67a644eb61/href">https://medium.com/media/5bedaab0e0fec378ebf00a67a644eb61/href</a></iframe><p>I wrote one post about how to run Protractor with PageObejct and Cucumber, if you need something about structure or some tips, just read.</p><p><strong>Post:</strong> <a href="https://medium.com/p/122537179ab7/">Automation with Protractor, PageObejct and Cucumber</a></p><p>My repository:</p><p><a href="https://github.com/tuliobluz/protractor-cucumber-pageobject">tuliobluz/protractor-cucumber-pageobject</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a461b1bf2e55" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automation with Protractor, PageObject and, Cucumber]]></title>
            <link>https://medium.com/@tuliobluz/automa%C3%A7%C3%A3o-com-protractor-pageobject-e-cucumber-122537179ab7?source=rss-6a68c08261a1------2</link>
            <guid isPermaLink="false">https://medium.com/p/122537179ab7</guid>
            <category><![CDATA[protractor]]></category>
            <category><![CDATA[cucumber]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[page-object]]></category>
            <category><![CDATA[bdd]]></category>
            <dc:creator><![CDATA[Túlio Bandeira Luz]]></dc:creator>
            <pubDate>Wed, 13 Jun 2018 17:20:19 GMT</pubDate>
            <atom:updated>2018-11-16T13:02:28.212Z</atom:updated>
            <content:encoded><![CDATA[<h4>Sharing what I did with Protractor</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*4RqwlaNAnZIcEVKE_0Mq7g.png" /></figure><p>I will show how to set up, which practice that I used to run protractor with the beautiful Page Object and Cucumber.</p><p><strong>What is </strong><a href="https://www.protractortest.org/#/"><strong>Protractor</strong></a><strong>?</strong></p><p>Protractor is an end-to-end test framework for Angular and AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.</p><p><strong>How does it </strong><a href="https://www.protractortest.org/#/infrastructure"><strong>work</strong></a><strong>?</strong></p><p>Protractor is an end-to-end test framework for AngularJS applications. Protractor is a Node.js program that supports the Jasmine and Mocha test frameworks.</p><p>Selenium is a browser automation framework. Selenium includes the Selenium Server, the WebDriver APIs, and the WebDriver browser drivers.</p><p>Protractor works in conjunction with Selenium to provide an automated test infrastructure that can simulate a user’s interaction with an Angular application running in a browser or mobile device.</p><p>Process Communication</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/0*GBSjKqIkayg1lObb" /></figure><p>The Protractor communication with Selenium Server it is by HTTP, the local server(selenium-server-standalone) or remotely(example: Sauces Labs) send the request by <a href="https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol">JsonWireProtocol </a>to run interacting in the browser(Chorme, Firefox ou outros).</p><p><strong>Why use </strong><a href="https://www.protractortest.org/#/"><strong>Protractor</strong></a><strong>?</strong></p><ul><li>Protractor is built on top of WebDriverJS, which uses native events and browser-specific drivers to interact with your application as a user would;</li><li>Protractor supports Angular-specific locator strategies, which allows you to test Angular-specific elements without any setup effort on your part;</li><li>You no longer need to add waits and sleeps to your test. Protractor can automatically execute the next step in your test the moment the webpage finishes pending tasks, so you don’t have to worry about waiting for your test and webpage to sync.</li></ul><h3>Hands-on</h3><p><strong>Set up</strong></p><ul><li>Prerequisite <a href="https://nodejs.org/en/download/">Node.js</a></li><li>Install Protractor globally: npm install <strong>-g</strong> protractor</li><li>Install the helper that download the browsers and instance of Selenium Server: webdriver-manager update</li><li>Start the server: webdriver-manager start should be print this log.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3wgI3MzUhc2U58rvy3VQFQ.png" /></figure><p>Obs.: Remember start the server when you will run the tests.</p><p>Tip: Good practice to name files</p><p>I like to let the name files with one default in the end like <strong>.po</strong> to PageObjects and <strong>.spec</strong> to specifications. This lets more easy to identify my files.</p><p>Example:</p><pre>login.po.js <br>login.spec.js</pre><p>Another example:</p><pre>loginPage.js <br>loginSpec.js</pre><p>Choose one to use and enjoy. :)</p><p><strong>Running the first test</strong></p><p>I created the following structure of folders to the first test:</p><pre>- tests<br>  |- e2e<br>    |- specs<br>- protractor.conf.js</pre><ul><li>I created a file calls <strong>protractor.conf.js</strong>, this file will be responsible for my properties of the project.</li></ul><p><strong>tests/e2e/protractor.conf.js</strong></p><pre>exports.config = {<br>  framework: &#39;jasmine&#39;,<br>  seleniumAddress: &#39;<a href="http://localhost:4444/wd/hub&#39;">http://localhost:4444/wd/hub&#39;</a>,<br>  specs: [&#39;./tests/e2e/specs/*.js&#39;]<br>}</pre><p>Only this tags on my config file will invoke the default configuration to others tags.</p><ul><li>I created a file inside my folder specs with name <strong>spec.js</strong></li></ul><p><strong>tests/e2e/specs/spec.js</strong></p><pre>1. describe(&#39;Protractor Demo App&#39;, function() {<br>2.   it(&#39;should have a title&#39;, function() {<br>3.     browser.get(&#39;http://juliemr.github.io/protractor-demo/&#39;);<br><br>4.     expect(browser.getTitle()).toEqual(&#39;Super Calculator&#39;);<br>5.   });<br>6. });</pre><ul><li><strong>Line 3</strong> calling the method get(‘<a href="http://www.angularjs.org&/#39;">http://www.angularjs.org&#39;</a>), the browser will open with the link.</li><li>L<strong>ine 4</strong> I’m waiting for the title of the page is (‘Super Calculator’), below is a screenshot about the page</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y_GqP3d_AYIjyMdpCAd-Ag.png" /></figure><ul><li>To run our test you will run the commands calling the config file(<strong>protractor.conf.js</strong>), remember to run on terminal inside the folder.</li></ul><pre><strong>protractor protractor.conf.js</strong></pre><ul><li><strong>Obs.:</strong> If your config file calls <strong>protractor.conf.js</strong>, you just need to run <strong>protractor</strong> in your terminal to run the tests.</li></ul><p>Result:</p><p>1 tests, 1 assertion, 0 failures.</p><p><strong>Can I use </strong><a href="https://www.protractortest.org/"><strong>Protractor </strong></a><strong>in application non angular?</strong></p><p>When you put the tag below on my <strong>protractor.conf.js</strong>, I’m telling to run the tests on applications non-angular.</p><pre>ignoreSynchronization: true,</pre><p><strong>BUT</strong>, using this property, my tests will become delayed, because of that, I must put the waits on my tests.</p><p><strong>Tip:</strong> “If my application that it is Angular there is a part non-angular, what I need to do”?</p><p>Using this tag on my tests to turn on or turn off:</p><pre>browser.<a href="https://www.protractortest.org/#/api?view=ProtractorBrowser.prototype.waitForAngularEnabled">waitForAngularEnabled</a>(false);</pre><p>Remember to use <a href="https://www.protractortest.org/#/api?view=ProtractorExpectedConditions">waits </a>on your tests, because it will be delayed</p><h3><strong>Page Object</strong></h3><p>When writing end-to-end tests, a common pattern is to use <a href="https://github.com/SeleniumHQ/selenium/wiki/PageObjects">Page Objects</a>. Page Objects help you write cleaner tests by encapsulating information about the elements on your application page. A Page Object can be reused across multiple tests, and if the template of your application changes, you only need to update the Page Object.</p><ul><li>Create the following structure of folders to use PageObject:</li></ul><pre>- tests<br>  |- e2e<br>    |- pages<br>       |- specs.po.js<br>    |- specs<br>       |- spec.spec.js<br>- protractor.conf.js</pre><p>Below it is the file structure to use PageObejct.</p><p><strong>tests/e2e/pages/spec.po.js</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c44398fd4cee754284a7f844911091ef/href">https://medium.com/media/c44398fd4cee754284a7f844911091ef/href</a></iframe><p>Above it is the specification file to use the Page Object</p><p><strong>tests/e2e/specs/spec.spec.js</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f8399a9f74745e5a4d18b62a1298ec81/href">https://medium.com/media/f8399a9f74745e5a4d18b62a1298ec81/href</a></iframe><ul><li>Line 1 <strong>spec.spec.js</strong>, instancing the PageObject that I will use in my tests.</li><li>Line 4 <strong>spec.spec.js</strong>, always that test be will call it will initialize the PageObject.</li><li>Line 6 <strong>spec.spec.js</strong>, the test calls the method of getting in PageObject in line 10 of <strong>spec.po.js</strong>, triggering get(‘<a href="http://www.angularjs.org&/#39;">http://www.angularjs.org&#39;</a>), the browser it will open in the link.</li><li>Line 7 <strong>spec.spec.js</strong>, the test calls the method <em>setName</em> of PageObject <strong>spec.po.js </strong>to send one parameter a string(‘Julie’), line 14 of <strong>spec.po.js </strong>the field is filled with received string.</li><li>Line 9 <strong>spec.spec.js</strong>, the test expects that the return text on the method specPage.getGreeintText() of <strong>spec.po.js</strong>, it be equal (‘Hello Julie!’).</li></ul><p>Run the test again:</p><pre><strong>protractor protractor.conf.js</strong></pre><ul><li><strong>Obs.:</strong> If your config file calls <strong>protractor.conf.js</strong>, you just need to run <strong>protractor</strong> in your terminal to run the tests.</li></ul><p>Result:</p><pre>1 spec, 0 failures</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/706/1*Pu3DJV4yoqs4Neji5idY0A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/380/1*fJYsLdxtpsIzJMkB5kZ9Eg.png" /></figure><p><strong>What is Cucumber?</strong></p><p><a href="https://cucumber.io/">Cucumber</a> is a tool for running automated tests written in plain language. Because they’re written in plain language, they can be read by anyone on your team. Because they can be read by anyone, you can use them to help improve communication, collaboration and trust on your team.</p><p><strong>Set up to Cucumber:</strong></p><p>How I used a Custom Framework to Protractor, so I must use <a href="http://www.chaijs.com/">Chai</a> library, to perform the expects in the tests:</p><p>To install:</p><pre>npm install — save-dev cucumber</pre><pre>npm install — save-dev protractor-cucumber-framework</pre><pre>npm install chai</pre><pre>npm install chai-as-promised</pre><ul><li>I created the following folder structure to <a href="https://github.com/cucumber/cucumber-js">cucumber</a>:</li></ul><pre>- tests<br>  |- e2e<br>    |- features<br>       |- spec.feature<br>    |- pages<br>       |- specs.po.js<br>    |- specs<br>       |- spec.spec.js<br>- protractor.conf.js</pre><p><strong>Config file to Cucumber:</strong></p><p><strong>protractor.conf.js</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d933cad0472de3f9ee94d28289a4308a/href">https://medium.com/media/d933cad0472de3f9ee94d28289a4308a/href</a></iframe><ul><li>Lines <strong>06 to 17</strong>, I put the preference about the browser, in my case I’m using the Chrome, but There are many options to use.</li><li>Lines <strong>42 and 43</strong>, It’s where I choose the framework that I using on my project, in this case, I’m using Cucumber, the new version of Protractor don’t have it, so I had to informed there is a custom framework if you want you can customize your profile.</li><li>Lines<strong> 45 to 47</strong>, this properties is to set up the feature files.</li><li>Line <strong>54</strong>, I put this property with true, at the end of every test, the browser will be restart(It become your tests delayed, I used this tag because, in my scenario I needed, I <strong>recommend </strong>don’t use this.).</li><li>Lines <strong>56 to 64</strong>, I informed the path to specification files.</li><li>Lines <strong>93 to 99</strong>, onPrepare is the pre-condition that it will be running before the tests, the lines <strong>96 to 99 </strong>I declared the cucumber global variables to use on the spec files.</li></ul><p>I didn’t need changes on PageObject file.</p><p><strong>tests/e2e/pages/spec.po.js</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/694506b1af837df6fd29ee948dce4b59/href">https://medium.com/media/694506b1af837df6fd29ee948dce4b59/href</a></iframe><p><strong>Using cucumber</strong></p><ul><li>I created the feature file <strong>spec.feature</strong>.</li></ul><p><strong>tests/e2e/features/spec.feature</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/38451d9adeb8e0d48704d9dabbaad34c/href">https://medium.com/media/38451d9adeb8e0d48704d9dabbaad34c/href</a></iframe><ul><li>I run the protractor: <strong>protractor protractor.conf.js</strong></li></ul><p>When I run the Protractor, it showed this log on the terminal.</p><p>Resultado:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/572/1*3p392Lu_VsTXBKx2wf_TFw.png" /></figure><p><strong>tests/e2e/specs/spec.spec.js</strong></p><ul><li>Then I needed to change the spec file, putting all functions inside the file <strong>spec.spec.js</strong>.</li></ul><p>Example:</p><pre>Given(&#39;The user go to {string}&#39;, function (string) {<br>           // Write code here that turns the phrase above into concrete actions<br>           return &#39;pending&#39;;<br>});</pre><ul><li>So, the final <strong>spec </strong>file using the <strong>PageObject </strong>must be similar that:</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/53d937d0482499222da69f5f728c6c41/href">https://medium.com/media/53d937d0482499222da69f5f728c6c41/href</a></iframe><ul><li>Line<strong> 1</strong> <strong>spec.spec.js</strong>, I’m instancing the PageObject that I will use in my tests.</li><li>Lines <strong>3 to 6</strong> instancing the library of chai, because I used this to assertions on tests.</li><li>Lines <strong>8 to 10</strong> I put the Before, that’s mean every time the test will run the function init() will initialize the object of PageObject.</li><li>Line <strong>15</strong> <strong>spec.spec.js, </strong>I called the function the<strong> get(string) of spec.po.js </strong>with the parameter a string (URL) received by<strong> spec.feature. </strong>Line <strong>6 spec.po.js, </strong>triggering the function get(string), the browser is open with the link.</li><li>Line <strong>19 spec.spec.js, </strong>I called the function <strong>setName(string) </strong>of <strong>spec.po.js </strong>with the parameter a string(name) received by <strong>spec.feature.</strong></li><li>Line <strong>23 to 24</strong> <strong>spec.spec.js</strong>, I expect that function <strong>specPage.getGreeintText()</strong> it will return one string and that string it will equal<em> </em>(‘Hello Julie’).</li></ul><p>Running the Protractor: <strong>protractor protractor.conf.js</strong></p><ul><li>The test will fail because the string I expect it is “Hello Julie!”, but the <strong>getGreeting()</strong> returned “Hello Tulio!”, bellow there is an example like the protractor showing the fail.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*srAniLQiMHGB-2RSYs1IEw.png" /></figure><p>To this test works I have to change the expect from<em>(‘Hello Julie!’) to</em> (‘Hello Tulio!’).</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F6nuiJjOOQBBn2%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F6nuiJjOOQBBn2%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2F6nuiJjOOQBBn2%2F200.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="249" frameborder="0" scrolling="no"><a href="https://medium.com/media/5cd23366d95596063949e5abaa2aa7ff/href">https://medium.com/media/5cd23366d95596063949e5abaa2aa7ff/href</a></iframe><p>Thank you so much, guys!!! I hope that you enjoy.</p><h3><strong>Conclusion</strong></h3><p>I hope this guide increase your knowledge base, I tried to do something easy and dynamic. I let some tips and good practices in this guide.</p><p>I was suffering a problem when I was doing this project, that I’m telling in this post: <a href="https://medium.com/@tuliobluz/protractor-session-id-is-null-using-webdriver-after-calling-quit-a461b1bf2e55">Protractor — Session ID is null. Using WebDriver after calling quit()?</a></p><p>Feel free to read too.</p><p>My repository that I used on this guide.</p><p><a href="https://github.com/tuliobluz/protractor-cucumber-pageobject">tuliobluz/protractor-cucumber-pageobject</a></p><p>You can check <strong>another structure </strong>to use <strong>Protractor </strong>in this repository:</p><p><a href="https://github.com/tuliobluz/protractor-supertest">tuliobluz/protractor-supertest</a></p><p><strong>Reference:</strong></p><ul><li><a href="https://www.protractortest.org/#/">Protractor - end-to-end testing for AngularJS</a></li><li><a href="https://semaphoreci.com/community/tutorials/getting-started-with-protractor-and-cucumber">Getting Started with Protractor and Cucumber</a></li><li><a href="https://cucumber.io/">BDD Testing &amp; Collaboration Tools for Teams | Cucumber</a></li><li><a href="https://github.com/cucumber/cucumber-js">GitHub - cucumber/cucumber-js: Cucumber for JavaScript</a></li><li><a href="http://www.chaijs.com/">Chai</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=122537179ab7" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>