Playwright for Browser Automation

Last week I held a short & sweet presentation in the company about the usage, benefits and drawbacks of Browser Remote Debugging APIs. One unfortunate problem we discovered was the lack of a standard across the browsers; every major browser maintains its very own implementation. The RemoteDebug – Intitiative tried to solve this problem, but until now without noticeable success, as you can see here by the lack of activity. Therefore, the Test and Development – World needed to deal with that all by themselves. A great team of ex Puppeteer-developers, who moved from Google to Microsoft, did exactly that by bringing us Playwright, a framework for writing automated tests encapsulating and using the various Remote Debugging Interfaces. In today’s short example we write a quick example test with Playwright.

Installing Playwright

As a starting prerequisite, we need a NodeJS-Distribution with Version 10 or greater. Next, we go to our already well-filled project directory and create a new NodeJS-Project:

$ cd /path/to/your/project/directory
$ mkdir playwright_test && cd playwright_test
$ npm init
$ npm install --save-dev playwright

While the installation progresses, you will notice that Playwright brings its own browser binaries. Don’t worry about that, they are still perfectly valid, as the rendering engines are not modified at all. Only the debugging capabilities have been given a few extensions.

Alright, that’s all we need.

Time to dive into the code!

Let’s assume we want to buy red shoes on Amazon, because we need new shoes, and red is a nice color.

// 1. We start by initializing and launching a non-headless Firefox 
// for demo purposes.
// (How do you call them, "headful"? "headded"? Feel free to drop me 
// your best shots. :))
const {firefox} = require("playwright");

(async () => {
  const browser = await firefox.launch({headless: false, slowMo: 50});
  const context = await browser.newContext();

  // 2. Next, we head to the Amazon Landing Page...
  const page = await context.newPage();
  await page.goto("https://www.amazon.com");
  
  // 3. ...do the search for Red Shoes...
  await page.fill("#twotabsearchtextbox", "Red Shoes");
  const searchBox = await page.$("#twotabsearchtextbox");
  await searchBox.press("Enter");

  // 4. ...and take a nice deep look at the page 
  // by saving a screenshot.
  await page.waitFor("img[data-image-latency='s-product-image']");
  await page.screenshot({path: "./screenshot.jpg", type: "jpeg"});
  
  // 5. Afterwards, we leave the testrun with a clean state.
  await browser.close();
})();

That’s it for now. From here, we can extend the test by doing elaborate verification steps, check out a nice pair of red shoes and pay them with our hard-earned testing money.  Feel free to check out the example’s full source code from here and go ham.

Conclusion

With Playwright we got a means to write automated tests with ease against the many different Remote Debugging APIs. It copes nicely with the API differences while preserving an intuitive and familiar JS test automation syntax.

So if you are looking for a more lightweight and lower level alternative to Selenium, give it a go!

Zalenium in a minimal Docker Compose – Setup

What is Zalenium?

Zalenium, brought to us by German online fashion retailer Zalando, is a feature-enriched Selenium test platform based on the popular Selenium Grid. Besides the core features like scaling Selenium test execution nodes, it provides nice things like video recording, a video player directly in the management UI and integrations with popular browser test tools like Sauce Labs. For a more detailed overview, please check out the project page. As far as we are concerned here, we have all the good arguments we need to fire up a small test setup. 🙂

What are we going to do?

In the following miniworkshop, we temporarily slip into the shoes of a devops engineer and set up a minimal Zalenium Grid – environment in order to execute remote Selenium tests there. The goal is that we use no more than 2 files (of resonable size):

  • the docker-compose-file to build and start the Zalenium-container provided by Zalenium
  • a sample selenium-webdriver-test to be executed inside Zalenium, kindly provided by Felipe Almeida, thank you very much.

For our experiment, I modified the latter to enable remote driver execution instead of starting a local firefox. Therefore, I prepared everything in a small bitbucket-repo.

Prereqs for the Zalenium Setup

  • a recent version of Docker (should already include docker-compose)
  • Ruby > 2.3.1 (I recommend using RVM)
  • a recent Chrome-browser
    • Unfortunately, my Firefox (v67.0.4) does not support the video format of the test execution recordings. 🙁

Steps

  1. Open a terminal and clone the repo.
  2. cd inside the new directory and fire up the containers: $ docker-compose up -d
  3. Start the test: $ ruby selenium_minimal.rb
  4. After the test execution, open a Chromeand head to the Dashboard: http://localhost:4444/dashboard/
  5. You should see one test execution in the list on the left side. Click it.
  6. Play the video and enjoy the action of your test.

Conclusion

Now that you have the power to quickly fire up Zalenium and its grid nodes, you can go further. Host it on a remote machine serving your needs as a Test Automaton Engine, move it to the cloud and go to town. This should step up your Quality Assurance Game in a scalable and easily maintainable way. Have fun!

RVM install in MacOS High Sierra: Problem – Solution

Preamble – the Problem

If you prefer your testautomation like i do – in Ruby within a version manager – then it is likely that you will eventually face the following situation in one or the other way:

Error running '__rvm_make - j4'
Please read [...]/make.log
There has been an error while running make.
Halting the installation.

A quick look into the mentioned make.log shows:

./miniruby: permission denied

In my case it happened, when i tried to conveniently install a Ruby from the 2.3 series using rvm:

rvm install 2.3.7

After a while full of painful investigation resulting in lots of „operation not permitted“, I decided to solve it in a pragmatic way: by using

rvm mount

The Solution: rvm mount

So what are we gonna do?

We will install Ruby from source to a custom directory first, and rvm mount it afterwards to make it available in RVM. We assume you have RVM installed already.

  1. First we need to make sure, that we have all required external dependencies. Usually openssl and gdbm are sufficient.  Do brew install openssl and brew install gdbm
  2. Download and extract the source of your favorite Ruby-version to your Downloads-directory. For example from: https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz (feel free to adapt the version to your target version)
  3. Open a terminal and move into the extracted folder.
  4. Do ./configure –with-gdbm-dir=“$(brew –prefix gdbm)“ –with-openssl-dir=“$(brew –prefix openssl)“ –prefix=RUBY_TARGET_DIR
    1. We have to specify gdbm’s and openssl’s installation directory, because brew installed these keg-only on my machine. That means it is installed, but not symlinked to /usr/bin or /usr/local/bin.
    2. RUBY_TARGET_DIR can be any custom directory you have free access to. I recommend smething like $HOME/rubies/<version key, e.g. 2.3.7/>
  5. Do make and make install.
  6. Now that we have our precious Ruby, where we want it to be, it is time to register it in RVM; do rvm mount /your/path/chosen/in/step4
  7. When prompted, give it a nice name and proceed. Don’t wonder, it will get prefixed with ext-. This is normal.
  8. Do rvm list and copy the name of your new Ruby.
  9. Do rvm use <the copied name> as usual.
  10. Check if your ruby is used correctly: Do ruby -v. It should display the expected ruby version.
  11. Go ahead and have fun with your new Ruby.

Epilogue

Starting from here, you achieved not only a Ruby that works, but also the freedom to build and install your favorite programming language exactly the way you want without missing out the cool features of a Ruby version manager and without any sudo-hassle. Maybe this way is a nice alternative for our fellow rbenv – users, too..? If you have a question, a better solution or any remarks, feel free to leave a comment. Otherwise, have a great day & rock on!!

3 Perks of being a Technical QA

The IT world flourishes and blooms superfast. New products and services pop up on a daily basis. We all know and work with these trends: while product managers want to ship new product features blazing fast, their fellow QA department invests time to „step back“ and make sure the shipping product increment does, what it is supposed to do. This of course creates a fragile balance in the release schedule. Now if we want to optimize the balance by applying upfront techniques like code reviews, TDD and test automation, the role of QA undergoes a slow but steady change. In my career, i saw a growing number of job offers in manual QA requiring more extensive technical knowledge. At least basic test automation skills and abilities to understand code are often required nowadays.

Following, I’d like to use my very first blog post to point out, why it is a good thing to have the mentioned technical skills in your QA career.

Almost 3 years ago, I joined the ranks of the QA as a Test Automation Engineer. Since then, I worked for many different projects & people in different roles. I met Lead Developers,  testers and CTOs of various companies. One of my most notable projects was the Logistics Department of a major food delivery company, which has a huge impact on the business, and therefore a great demand for quality. The team consisted almost only of developers and one (part-time) product manager. The logistics monitoring tool the team built is based on Ruby on Rails; a huge advantage for me, because my test automation stack is based on Ruby & Cucumber, that fits neatly into Rails. With this setup in mind, lets dive into the real questions: how can technical proficiency help you increase quality?

1. Static Code Analysis & Code Reviews

Highly underestimated in the testing departments, CR-techniques bring quality on a detailed level to the desk. Static analysing tools like Codeclimate or Scrutinizer already automate a great share of the efforts and provide the development team and you with valuable metrics and advice. With code reviews, you can complement these valuable results even more. Usually a task for developers, you as a QA can bring a different, more destructive, perspective to code discussions. This way, you may discover additional potential issues or convention breaks, that the developers may have not seen. Most Git-Providers come with easy diff tools to reduce your effort making all these nice things very cheap.

2. The Glue between Dev, QA & Product

As a technical QA you have many different insights at your disposal. When it comes to  typical discussions in every day’s sprint life, you are in close contact to the manual testers  leveraging yourself to absorb everything from the product design side. Then you can transfer the knowledge back to Dev and, equally interesting, vice versa. You can estimate & answer relevant questions from multiple perspectives.

3. Openings for more

Tech enables you to deliver even more forms of quality. For one project, I coded Performance- and Stress Tests directly in the Rails app using ruby-jmeter and made them part of the Rake-Scripts. Rake is the conventional build system similar to Make for Ruby on Rails – Projects. This enabled me to execute them on demand and could even serve next to your automated functional texts in  scheduled test execution environments. All that while they are managed directly in the project’s Git-Repo as the source code files they are. Another big opportunity is release management, where you can play a big role. As scheduled or on-commit test executions play a major role in answering the question „Can we deploy?“, you are able to actively shape the CI/CD flow directly with the CI/CD-Tool of your choice bringing you directly to the heart of the release process for a lot of companies.

Technical QA – hot or not?

If you feel a knack for the technology around you, and if you want to explore that nefarious destructive glare in your eyes, I absolutely recommend you to go for it. You have nothing to lose and lots of interesting opportunities to gain. I made the experience that the entry is pretty smooth, and the basic technologies around Selenium or Jenkins for example are well known, documented and supported. Therefore, dive into it and prepare for adventure. 🙂

You want to have a smooth quickstart? Check out my minimal Zalenium Setup!