It's All Writing.

Writing makes you happy.

How to make a End-to-End Testing by WebdriverIO and Microsoft Excel.

I explained the way to convert xlsx to JSON and a basis of WebdriverIO by entry in last time and the time before last.
Now, I’ll explain “How to make a End-to-End Testing by WebdriverIO and Microsoft Excel.”.

Prepare

Now, I’ll prepare the easy form for the test target.
It’s very simple. The code is below.

<html>
  <body>
<?php
    if ( isset( $_POST['name'] ) || isset( $_POST['hobby'] ) || isset( $_POST['birthday'] ) ) {
        echo <<<EOM
    <div>
      <div>
        Name: <span id="name">{$_POST['name']}</span>
      </div>
      <div>
        Hobby: <span id="hobby">{$_POST['hobby']}</span>
      </div>
      <div>
        Birthday: <span id="birthday">{$_POST['birthday']}</span>
      </div>
      <div>
        <a href="#" onclick="history.back();">back</a>
      </div>
    </div>
EOM;
    } else {
        echo <<<EOM
    <form action="{$_SERVER['SCRIPT_NAME']}" method="POST" id="profile_form">
      <div>
        <div>
          Name: <input type="text" name="name" id="name" />
        </div>
        <div>
          Hobby: <input type="text" name="hobby" id="hobby" />
        </div>
        <div>
          Birthday: <input type="text" name="birthday" id="birthday" />
        </div>
      </div>
      <div>
        <input type="submit"/>
      </div>
    </form>
EOM;
    }
?>
  </body>
</html>

Don’t get angry!
I know that this code is very very bad.
I’ll fix that! So, Don’t mail me about it.
( And never use this code! )

Make Tests

Now, let’s make tests.
I’ll show you a simple example below.

var expect = require('chai').expect;
describe('submiting form result', function() {
    it('should have input data', function () {
        let input_name = 'TAKAHIRO SHINCHI';
        let input_hobby = 'Walking';
        let input_birthday = '1979/01/03';

        let url = 'http://its-all-writing.com/sample/3rd-form.php';

        /* form  page */
        browser.url(url);
        browser.waitForVisible('#name');
        browser.setValue('#name', input_name);
        browser.waitForVisible('#hobby');
        browser.setValue('#hobby', input_hobby);
        browser.waitForVisible('#birthday');
        browser.setValue('#birthday', input_birthday)
        browser.submitForm('#profile_form');

        /* result page */
        expect($('#name').getText()).to.be.equal(input_name);
        expect($('#hobby').getText()).to.be.equal(input_hobby);
        expect($('#birthday').getText()).to.be.equal(input_birthday);
    });
});

It’s looks good.
But when testing combination of a lot of input value, We have to rewrite a code one by one, if it goes on.
It’s so tired and dangerous. So, we’ll separate test with data and cord.

Make Test Data

Now, where is a test data written?
Yes, it’s Microsoft Excel.
Excel is simple to change to JSON as I explained by the entry in the past.
And, Excel is one of the most suitable tools for the person who isn’t a programmer to write the specification.( <= It’s very very important!! )
By using Excel, You can ask to maintain a test data for someone else – That person a head won’t be strangely even if Excel is being operated so throughout the day -.
All joking aside, even if you maintain a test cord and data by yourself, it’s useful to manage data using Excel.

I’ll show you a example of test data on xlsx below.

specification.xlsx. first sample.

I’ll put this file in the test/data/ directory under the name as specification.xlsx.

Execute End-to-End Testing

So, I’ll modify a test code so that data may be read using specification.xlsx.

var expect = require('chai').expect;

const xlsx = require('xlsx');
const utils = xlsx.utils;

const specification_xlsx_path = 'test/data/specification.xlsx';

let workbook = xlsx.readFile(specification_xlsx_path);
let worksheet = workbook.Sheets['data'];
let json = utils.sheet_to_json(worksheet);

describe('submiting form result', function() {
    it('should have input data', function () {

        let url = 'http://its-all-writing.com/sample/3rd-form.php';

        for (let i=0; i<json.length; i++) {

            let name = json[i]['name'] ? json[i]['name'] : '';
            let hobby = json[i]['hobby'] ? json[i]['hobby'] : '';
            let birthday = json[i]['birthday'] ? json[i]['birthday'] : '';

            /* form  page */
            browser.url(url);
            browser.waitForVisible('#name');
            browser.setValue('#name', name);
            browser.waitForVisible('#hobby');
            browser.setValue('#hobby', hobby);
            browser.waitForVisible('#birthday');
            browser.setValue('#birthday', birthday);
            browser.submitForm('#profile_form');

            /* result page */
            expect($('#name').getText()).to.be.equal(name);
            expect($('#hobby').getText()).to.be.equal(hobby);
            expect($('#birthday').getText()).to.be.equal(birthday);

        }
    });
});

Fix XSS

There is a big problem with this form so that everyone may notice so. It’s XSS.
Now, I’ll add test data to try XSS attack, and prepare the appropriate data which should be displayed on result page that fixed XSS.
I’ll show you a modified specification.xlsx below.

specification.xlsx. second sample. it has data of xss attack.

And, You’ll get test result below.

$ ./node_modules/.bin/wdio wdio.conf.js 
------------------------------------------------------------------
[chrome #0-0] Session ID: e01006387e337004409be8750cd316bf
[chrome #0-0] Spec: /path/to/your_project/test/specs/3rd-form.spec.js
[chrome #0-0] Running: chrome
[chrome #0-0]
[chrome #0-0] submiting form result
[chrome #0-0]   1) should have input data
[chrome #0-0]
[chrome #0-0]
[chrome #0-0] 1 failing (8s)
[chrome #0-0]
[chrome #0-0] 1) submiting form result should have input data:
[chrome #0-0] expected '' to equal '<script type="text/javascript">conole.log(\'XSS\');</script>'
[chrome #0-0] AssertionError: expected '' to equal '<script type="text/javascript">conole.log(\'XSS\');</script>'
[chrome #0-0]     at Context.<anonymous> (/path/to/your_project/test/specs/3rd-form.spec.js:34:48)
[chrome #0-0]     at new Promise (<anonymous>)
[chrome #0-0]     at new F (/path/to/your_project/node_modules/core-js/library/modules/_export.js:35:28)
[chrome #0-0]

Wrote xunit report "WDIO.xunit.chrome.0-0.xml" to [./wdio-logs/].


0 passing (9.50s)
1 failing

Then, Let’s correct XSS of the form.
Fixed code is below.

<html>
  <body>
<?php
    if ( isset( $_POST['name'] ) || isset( $_POST['hobby'] ) || isset( $_POST['birthday'] ) ) {
    $name = htmlspecialchars($_POST['name'], ENT_QUOTES);
    $hobby = htmlspecialchars($_POST['hobby'], ENT_QUOTES);
    $birthday = htmlspecialchars($_POST['birthday'], ENT_QUOTES);
        echo <<<EOM
    <div>
      <div>
        Name: <span id="name">$name</span>
      </div>
      <div>
        Hobby: <span id="hobby">$hobby</span>
      </div>
      <div>
        Birthday: <span id="birthday">$birthday</span>
      </div>
      <div>
        <a href="#" onclick="history.back();">back</a>
      </div>
    </div>
EOM;
    } else {
        echo <<<EOM
    <form action="{$_SERVER['SCRIPT_NAME']}" method="POST" id="profile_form">
      <div>
        <div>
          Name: <input type="text" name="name" id="name" />
        </div>
        <div>
          Hobby: <input type="text" name="hobby" id="hobby" />
        </div>
        <div>
          Birthday: <input type="text" name="birthday" id="birthday" />
        </div>
      </div>
      <div>
        <input type="submit"/>
      </div>
    </form>
EOM;
    }
?>

Try to run test.

$ ./node_modules/.bin/wdio wdio.conf.js
------------------------------------------------------------------
[chrome #0-0] Session ID: 37844115468ac92eaf8906633cdcd4f8
[chrome #0-0] Spec: /path/to/your_project/test/specs/3rd-form.spec.js
[chrome #0-0] Running: chrome
[chrome #0-0]
[chrome #0-0] submiting form result
[chrome #0-0]   ✓ should have input data
[chrome #0-0]
[chrome #0-0]
[chrome #0-0] 1 passing (8s)
[chrome #0-0]

Wrote xunit report "WDIO.xunit.chrome.0-0.xml" to [./wdio-logs/].


1 passing (9.80s)

Success! It’s all green!
And, you can check the form here.

Summary

Test can be divided into data and the test code by using Excel and WebdriverIO.
I increased Maintainability of the test cord by this, and showed that you could also add easily the pattern of the combination of various test data.
By the feature, you can also inspect and fix problems like XSS easily.