Viewing Category: Selenium  [clear category selection]

Nightwatch.js and CKEditor

I've been creating functional tests using Nightwatch.js recently. This tool uses Node.js and a simple testing framework. It's a refreshing switch from using JUnit and the Selenium Java library to write tests, yet it uses the same Selenium protocol to drive browsers with WebDriver and generates the same JUnit XML test results. I have Jenkins running a batch of Nightwatch.js tests in a job triggered after deploy. There are still some things I'm figuring out, but nothing has blocked moving forward yet.

One of the challenges that needed to be addressed was setting content inside a CKEditor. This is tricky because the editor is nested inside an iframe. After a bunch of experimentation, I settled on this method for saving a form containing a WYSIWYG component:

That test will connect to the CKEditor demo page and replace the content within, then take a screenshot like this:

Next challenge to handle: uploading files using a web application that dynamically generates the HTML elements.

Mixing Selenium and jQuery

Consider that you have a Selenium test case that creates a new record in the database, then checks to make sure that the save action caused the record to appear on some other page. It can be a bit tricky to locate the identifier/primary key/whatever on the page reliably. Here's what I do:

<tr> <td>store</td> <td>Teh Awesome</td> <td>name</td> </tr> <tr> <td>open</td> <td>/suchandsuch/form</td> <td></td> </tr> <tr> <td>type</td> <td>name</td> <td>${name}</td> </tr> <tr> <td>clickAndWait</td> <td>submit</td> <td></td> </tr>

Now a new record should exist. I go looking for it.

<tr> <td>open</td> <td>/suchandsuch/index</td> <td></td> </tr> <tr> <td>storeEval</td> <td>this.browserbot.getUserWindow().jQuery("td a:contains('${name}')").attr("href").replace(/\D/g, "")</td> <td>id</td> </tr> <tr> <td>assertEval</td> <td>parseInt(${id}, 10) > 0</td> <td>true</td> </tr> <tr> <td>open</td> <td>/suchandsuch/detail/${id}</td> <td></td> </tr> <tr> <td>assertTextPresent</td> <td>${name}</td> <td></td> </tr>

So now the Selenium variable named id contains the identifier I'm interested in. I expect it to be a positive integer. And I want to make sure the name exists on the page. The trick is to use the Selenium browserbot object to gain access to jQuery loaded on every page of the application. I could have included jQuery in a Selenium plugin, but it's not necessary.