How it works
Kakunin is built with no-js
experience in mind. Because of that you're able to test even complicated apps just
by knowing Kakunin (Gherkin) steps and a few good practices.
Concepts
Kakunin uses cucumber-js
internally, because of that all tests (or rather scenarios) are using Gherkin
as a "programming"
language.
A simple scenario could look like this:
Feature:
Scenario: Display user profile for logged user
Given I am logged in as a "user"
When the "dashboard" page is displayed
And I click the "profileButton" element
Then the "myProfile" page is displayed
And the "myName" element is visible
This is how most of Kakunin test scenarios look like.
There are a few concepts to be explained.
Page objects
Page object is a code representation of a page displayed in browser. Kakunin has built-in BasePage
page object, that you should extend.
Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.
A very simple example of Kakunin's Page Object could look like the following:
const { BasePage } = require('kakunin');
class DashboardPage extends BasePage {
constructor() {
super();
this.url = '/dashboard';
}
}
module.exports = DashboardPage;
As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (this.url
).
This code should be saved inside pages
directory in a file with js
extension.
Note that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:
When the "dashboard" page is displayed
expects that there is a file named dashboard.js
inside the pages
directory.
Every step that we are using is somehow connected to an object called currentPage
. This object value is set to a
page object that we expect to be on.
This is done by two kinds of steps:
Then the "dashboard" page is displayed
- this one checks if current url in browser is the same as the one inside Page Object and changes a value of thecurrentPage
field to this page objectWhen I visit the "dashboard" page
- this one goes to the url specified in Page Object and attaches the Page Object to thecurrentPage
field as above
This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods. For example, having the following code:
Feature:
Scenario: Display user profile for logged user
Given I am logged in as a "user"
When the "dashboard" page is displayed
And I click the "profileButton" element
Then the "myProfile" page is displayed
And the "myName" element is visible
The step named And I click the "profileButton" element
is executed in context of dashboard
Page Object, thus we can assume that profileButton
should be defined inside the
pages/dashboard.js
file.
At the same time the step And the "myName" element is visible
is executed in context of myProfile
, so myName
should be defined in pages/myProfile.js
file.
Elements and locators
The second concept that you have to understand are elements and locators.
Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:
And the "myName" element is visible
.
Defining elements is very simple. Let's say we have such page object:
const { BasePage } = require('kakunin');
class DashboardPage extends BasePage {
constructor() {
super();
this.url = '/dashboard';
}
}
module.exports = DashboardPage;
Elements should be defined inside constructor
method. Let's add element for myName
:
const { BasePage } = require('kakunin');
class DashboardPage extends BasePage {
constructor() {
super();
this.url = '/dashboard';
this.myName = element(by.css('.myName'));
}
}
module.exports = DashboardPage;
As you see we added a single line this.myName = element(by.css('.myName'));
.
by.css('.myName')
- is a locator, this is a standard protractor syntax, you can read more on protractors documentation
By joining element
method with a locator, we created element to be used by our steps.