SlideShare a Scribd company logo
KAKUNIN
E2E REINVENTED
ADAM POLAK
PHP DEVELOPER
JS DEVELOPER
E2E DEVELOPER
E2E DEVELOPER
JS DEVELOPER
TOMASZ GÓRSKI
KAKUNIN WORKSHOPS
AGENDA
▸ HOW TO INSTALL AND CONFIGURE KAKUNIN?
▸ HOW TO NAVIGATE BETWEEN PAGES AND
VALIDATE CURRENT PAGE?
▸ HOW TO INTERACT WITH ELEMENTS AND
VALIDATE CONTENT?
▸ HOW TO FILL IN, CHECK OUT ITS VALUES AND
VALIDATE FORMS?
▸ HOW TO CHECK EMAILS CONTENT?
▸ HOW TO DEBUG KAKUNIN?
KAKUNIN WORKSHOPS
▸ HOW TO EXTEND KAKUNIN WITH CUSTOM STEPS?
▸ HOW TO HANDLE NON-BUILT-IN FORM FIELD
TYPES?
▸ HOW TO ADD SCENARIO SPECIFIC HOOKS?
▸ HOW TO CONNECT DIFFERENT MAILING SERVICE?
AGENDA
WHAT IS KAKUNIN?
KAKUNIN WORKSHOPS
WHAT IS KAKUNIN?
▸ PROTRACTOR EXTENSION
▸ GHERKIN AS A PROGRAMMING LANGUAGE
▸ BUILT-IN STEPS TO SOLVE MOST COMMON CASES
▸ EASLY EXTENDABLE
▸ HANDLES ANGULAR AND NON-ANGULAR APPS
OUT OF THE BOX
KAKUNIN
WHAT ARE WE GOING TO
TEST?
KAKUNIN WORKSHOPS
INSTALATION
HOW TO INSTALL?
{
"name": "workshop",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "",
"license": "ISC"
}
cd kakunin-workshop
mkdir kakunin-workshop
npm init
INSTALATION
HOW TO INSTALL?
npm install webdriver-manager

npm install protractor

npm install kakunin
{
...
"scripts": {
...
"kakunin": "NODE_ENV=prod kakunin"
},
...
"devDependencies": {
...

"webdriver-manager": "12.0.6",
"protractor": "5.1.2",
"kakunin": "1.0.1"
}
}
INSTALATION
HOW TO INSTALL?
npm run kakunin init
cd step_definitions

ln -s ../node_modules/kakunin/dist/step_definitions/elements.js kakunin-elements.js
ln -s ../node_modules/kakunin/dist/step_definitions/debug.js kakunin-debug.js
ln -s ../node_modules/kakunin/dist/step_definitions/file.js kakunin-file.js
ln -s ../node_modules/kakunin/dist/step_definitions/form.js kakunin-form.js
ln -s ../node_modules/kakunin/dist/step_definitions/email.js kakunin-email.js
ln -s ../node_modules/kakunin/dist/step_definitions/generators.js kakunin-generators.js
ln -s ../node_modules/kakunin/dist/step_definitions/navigation.js kakunin-navigation.js
INSTALATION
HOW TO INSTALL?
npm run kakunin
Scenario:
If you can see this in console then hook is working properly.
✔ When I visit the "page" page
✔ And I generate random "name" as "myName"
✔ Then my matcher "e:name" matches "v:myName"
✔ And my matcher "e:name" matches "Bob"
1 scenario (1 passed)
4 steps (4 passed)
0m00.757s
INSTALATION
HOW TO RUN A SINGLE SCENARIO?
npm run kakunin -- --tags @someTag
npm run kakunin -- --tags="@someTag and @otherTag"
npm run kakunin -- --tags="@someTag or @otherTag"
npm run kakunin -- --tags="not @someTag"
NAVIGATE BETWEEN
PAGES
KAKUNIN WORKSHOPS
NAVIGATE BETWEEN PAGES
PAGE OBJECT
const { BasePage } = require('kakunin');
class MainPage extends BasePage {
constructor() {
super();
this.url = '/';
}
}
module.exports = new MainPage();
NAVIGATE BETWEEN PAGES
SCENARIO - NAVIGATING
Feature: Load main page
Scenario: Load main page as homepage
Given/When I visit the "main" page
The name of a page object file. For this case there has to be a file "main.js" in pages directory.
NAVIGATE BETWEEN PAGES
SCENARIO - CHECKING OUT ON WHAT PAGE WE ARE
Then the "main" page is displayed
The name of a page object file. For this case there has to be a file "main.js" in pages directory.
NAVIGATE BETWEEN PAGES
SCENARIO - DEBUGGING
Give/When/Then I wait for "20" seconds
Give/When/Then I pause
NAVIGATE BETWEEN PAGES
WHAT ABOUT URL WITH PARAMETERS ?
/suppliers/some-supplier-id/clients/some-client-id
/suppliers/:supplierId/clients/:clientId
...
this.url = '/suppliers/:supplierId/clients/:clientId';
...
NAVIGATE BETWEEN PAGES
PAGE CONTEXT
Then the "main" page is displayed
EVERY BUILT-IN STEP (EXCEPT NAVIGATION
ONES) WILL HAVE AN ACCESS TO MAIN PAGE
OBJECT.
INTERACTING WITH
ELEMENTS
INTERACTING WITH ELEMENTS
INTERACTING WITH ELEMENTS
Then the "showActive" element is visible
The name of a selector from current page object file.
ELEMENT VISIBILITY
INTERACTING WITH ELEMENTS
SELECTORS
▸ defines access to element
▸ support for protractor locators

http://www.protractortest.org/#/api?
view=ProtractorBy
▸ support for angular only attributes
INTERACTING WITH ELEMENTS
SELECTORS
▸ id attribute, custom attribute, custom class, unique class - GOOD
▸ for angular app: ng-model, ng-repeat - GOOD
▸ html tag - BAD
▸ angular validation classes (ng-valid, ng-pristine etc) - VERY BAD
INTERACTING WITH ELEMENTS
SELECTORS
this.mySelectorName = $('.css-selector');
this.mySelectorName = $('html-tag');
this.mySelectorName = $('html-tag.css-selector');
this.mySelectorName = element(by.repeater('project in projects'));
INTERACTING WITH ELEMENTS
Then the "showActive" element is visible
ELEMENT VISIBILITY - PROBLEM
THE ELEMENT MUST BE VISIBLE RIGHT AWAY.
IT DOES NOT WAIT FOR ELEMENT TO BE
VISIBLE.
INTERACTING WITH ELEMENTS
When/Given/Then I wait for "visibilityOf" of the "showActive" element
ELEMENT VISIBILITY - SOLUTION
uses protractors expected conditions internally, for example
visibilityOf
invisibilityOf
INTERACTING WITH ELEMENTS
ELEMENT VISIBILITY - WHAT ELSE?
When/Given/Then the "showCompleted" element is present
When/Given/Then the "showCompleted" element is not visible
When/Given/Then the "showCompleted" element is not present
INTERACTING WITH ELEMENTS
When I fill the "myForm" form with:
| fieldSelector | value to be used |
Form selector
Input selector
this.myForm = $('.add-todo');
this.fieldSelector = $('.add-todo input[name="add-todo"]');
FILLING UP FORM
INTERACTING WITH ELEMENTS
Then the "myForm" form is filled with:
| fieldSelector | value to be used |
Form selector
Input selector
CHECKING OUT FORM VALUE
INTERACTING WITH ELEMENTS
WHAT ABOUT DIFFERENT FIELD TYPES?
▸ supports all of the basic html field types (radio, checkbox, textarea, select, file, text)
▸ allows to add custom made handlers for field types
INTERACTING WITH ELEMENTS
HOW ABOUT SUBMITTING ?
When I click the "addTodoButton" element
The name of a selector from current page object file.
CUSTOM STEPS
CUSTOM STEPS
CUSTOM STEPS
OUR STEP
Given I am logged in as an "submitter"
User role
CUSTOM STEPS
CUCUMBER 2.0 - STEP DEFINITION
const { defineSupportCode } = require('kakunin');
defineSupportCode(({ Given }) => {
Given(/^I am logged in as an "([^"]*)"$/, function (user) {
return Promise.resolve();
});
});
CUSTOM STEPS
ACCESS PAGE FROM CODE
const myPage = browser.page.myPage;
CUSTOM STEPS
BASE PAGE METHODS
visit()
click(elementSelectorName)
isDisabled(elementSelectorName)
isPresent(elementSelectorName)
isVisible(elementSelectorName)
isOn()
CUSTOM STEPS
BASE PAGE METHODS
getNumberOfElements(elementSelectorName)
scrollIntoElement(elementSelectorName, optionalIndexForArrayElement)
CUSTOM STEPS
BASE PAGE METHODS
fillForm(formData)
[
[
'fieldSelector',
'fieldValue'
]
]
checkForm(formData)
[
[
'fieldSelector',
'fieldValue'
]
]
CUSTOM STEPS
BASE PAGE METHODS
fillField(fieldSelector, fiedlValue)
checkField(fieldSelector, fiedlValue)
EVERY METHOD RETURNS A PROMISE
CUSTOM STEPS
USER PROVIDER
this.userProvider.getUser(userName);
accounts: {
userName: {
accounts: [
{
email: 'some@email.com',
password: 'somePassword'
}
]
}

}
CUSTOM STEPS
USER PROVIDER
this.currentUser = {
account: {
email: 'some@email.com',
password: 'somePassword'
},
type: "userName"
}
HOOKS
HOOKS
HOOKS
HOOK DEFINITION
const { defineSupportCode } = require('kakunin');
defineSupportCode(({ After }) => {
After(() => {

return Promise.resolve();

});
});
defineSupportCode(({ After }) => {
After('@someTag', () => {

return Promise.resolve();

});
});
HOOKS
HOOK DEFINITION - EXECUTE REMOTE JS CODE
protractor.browser.executeScript('your js code to be run inside a browser');
HOOKS
HOOK DEFINITION - CLEAR COOKIES
protractor.browser.manage().deletAllCookies();
HOOKS
RESTORE APP STATE
FIXTURES_RELOAD_HOST=http://192.168.99.100/app_e2e.php/_e2e/load_fixtures
@reloadFixtures
CUSTOM HANDLERS
HANDLERS
CUSTOM HANDLERS
INTERFACE
isSatisfiedBy(element, elementName) {
return Promise.resolve();
}
handleFill(page, elementName, desiredValue) {
return Promise.resolve();
}
handleCheck(page, elementName, desiredValue) {
return Promise.resolve();
}
getPriority() {
return 1000;
}
CUSTOM HANDLERS
HANDLER SERVICE - ADDING NEW HANDLER
const { handlers } = require('kakunin');
class MyHandler {}
handler.addHandler(new MyHandler());
CUSTOM HANDLERS
CUSTOM SELECT HTML
<div class="form__field serviceMarket form__field--danger">
<label class="form__label form__label--required">Service Market</label>
<div class="Select Select--single is-clearable is-focused is-open">
<div class="Select-control">
</div>
<div class="Select-menu-outer">
<div role="listbox" class="Select-menu">
<div style="overflow: visible; width: 0px;">
<div aria-label="grid" class="ReactVirtualized__Grid ReactVirtualized__List
VirtualSelectGrid">
<div class="ReactVirtualized__Grid__innerScrollContainer">
<div class="select__option" data-e2e="/app_e2e.php/service_markets/
80a06089-2f94-4992-8f7c-1d30fc7b8a3e">SME Services</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
CUSTOM HANDLERS
CUSTOM SELECT HTML - SELECTED OPTION
<div class="form__field serviceMarket">
<label class="form__label form__label--required">Service Market</label>
<div class="Select Select--single is-clearable has-value">
<input type="hidden" name="serviceMarket" value="/app_e2e.php/service_markets/
80a06089-2f94-4992-8f7c-1d30fc7b8a3e">
</div>
</div>
TRANSFORMERS
TRANSFORMERS
TRANSFORMERS
A WAY TO GENERATE OR TRANSFORM VALUES FROM

HUMAN READABLE VERSION TO APP USABLE.
TRANSFORMERS
g:generatorName:param1:param2:param...N
AVAILABLE TRANSFORMERS
d:dictionaryName:dictionaryKeyName
v:variableName
TRANSFORMERS
When I fill the "myForm" form with:
| projectUrl | http://some-url.com |
| projectType | 1234 |
WITHOUT TRANSFORMERS
When I fill the "myForm" form with:
| projectUrl | g:projectUrl |
| projectType | d:projectTypes:website |
WITH TRANSFORMERS
TRANSFORMERS
GENERATORS
const { generators } = require('kakunin');
class ProjectUrlGenerator{
isSatisfiedBy(name) {
return this.name === 'projectUrl';
}
generate(params) {
return Promise.resolve('http://some-url.pl');
}
}
generators.addGenerator(new ProjectUrlGenerator());
TRANSFORMERS
DICTIONARIES
const { dictionaries } = require('kakunin');
class ProjectTypesDictionary{
constructor() {
this.values = {
'myServiceMarket':'/service_markets/80a06089-2f94-4992-8f7c-1d30fc7b8a3e'
};
this.name = 'projectTypes';
}
isSatisfiedBy(name) {
return this.name === name;
}
getMappedValue(key) {
return this.values[key];
}
}
dictionaries.addDictionary(new ProjectTypesDictionary());
EMAILS
EMAILS
EMAILS
CONFIGURATION
email: {
type: 'mailtrap',
config: {
apiKey: '81279e9fb9351ebdf7aefef89e6a5701',
inboxId: '203459',
url: 'https://mailtrap.io/api/v1'
}
},
clearEmailInboxBeforeTests: true
mailer_host: smtp.mailtrap.io
mailer_user: efb44191c15785
mailer_password: 821a734f231165
mailer_port: 2525
mailer_default_from: example@example.com
EMAILS
CHECKING EMAILS
Then the email has been sent:
| currentUser | | | |
| subject | some subject | | |
| html_body | some id | | |
| file | some file | PDF | 9000 |
ALLOWS TO FILTER EMAIL CONTENT
BY MULTIPLE FILEDS
EMAILS
CHECKING EMAILS - FILTERS
▸ currentUser - checks if email was sent to current logged user, requires integration with Kakunin User
Provider
▸ subject - allows to check email subject
▸ html_body - allows to check content of email
▸ file - allows to check attachments, it's type, name and size
ALL FILTERS SUPPORT MATCHERS
REGULAR EXPRESSIONS
REGULAR EXPRESSIONS
REGULAR EXPRESSIONS
CUSTOM REGEX
module.exports = {
matchingStoreId: '(STORE-[0-9]{6}-[0-9]{4})',
emailSubject: '(Join Our Store - STORE-[0-9]{6}-[0-9]{4}‫اﻟﯿﻨﺎ‬ ‫اﻧﻀﻢ‬ -)'
};
USAGE
r:matchingStoreId
CONTENT VALIDATION
CONTENT VALIDATION
CONTENT VALIDATION
FORM VALIDATIONS
Then the error messages should be displayed:
| element | errorMessage |
| nameValidationMsg | This value should not be blank. |
| targetMarketSegmentValidationMsg | This value should not be blank. |
this.nameValidationMsg = $('.name .form__error');
CONTENT VALIDATION
VALIDATE ELEMENT CONTENT
Then there are "equal 1" "todos" elements
uses chai.js expectations
equal X
above X
between X Y
at least X
CONTENT VALIDATION
VALIDATE ELEMENT CONTENT
Then there are "equal 1" "todos" elements
REQUIRES LIST SELECTOR
CONTENT VALIDATION
VALIDATE ELEMENT CONTENT
Then there are "equal 1" "todos" elements
this.todos = $$('ul li');
this.todos = element.all(by.css('ul li'));
CONTENT VALIDATION
VALIDATE ELEMENT CONTENT
Then there is element "myElement" with value "r:notEmpty"
Then there is element "myElement" with value "t:some text"
Then there is element "myElement" with value "f:isClickable"
MATCHERS
CONTENT VALIDATION
ALLOW TO VALIDATE FILED VALUE, BUT ALSO
BEHAVIOUR (FOR EXAMPLE IF ELEMENT IS

CLICKABLE)
CONTENT VALIDATION
CUSTOM MATCHER
const { matchers } = require('kakunin');
class MyMatcher {
isSatisfiedBy(prefix, name) {
return prefix === 'm:' && name === 'pending';
}
match(protractorElement, matcherName) {
return protractorElement.getText().then((value) => value === 'pending');
}
}
matchers.addMatcher(new MyMatcher());
CONTENT VALIDATION
CONTENT VALIDATION
VALIDATE ELEMENT CONTENT - DETAILED CHECK
Then there are "equal 1" following elements for element "todos":
| element | value |
| removeButton | f:isVisible |
REQUIRES LIST SELECTOR
CHILD ELEMENTS MUST BE LOCATORS, NOT ELEMENTS
CONTENT VALIDATION
this.todos = $$('ul li');
Then there are "equal 1" following elements for element "todos":
| element | value |
| removeButton | f:isVisible |
this.removeButton = by.css('.remove');
VALIDATE ELEMENT CONTENT - DETAILED CHECK
FILE DOWNLOAD
CONTENT VALIDATION
CONTENT VALIDATION
FILE DOWNLOAD
Then the file "fileName.extension" should be downloaded
downloaded file name, the same as the one normally have in browser
CONTENT VALIDATION
FILE DOWNLOAD - CLEAR DOWNLOAD DIRECTORY
@downloadClearAfter
@downloadClearBefore
QUESTIONS ?
KAKUNIN WORKSHOPS
THANK YOU
Ad

More Related Content

What's hot (20)

React & redux
React & reduxReact & redux
React & redux
Cédric Hartland
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
React и redux
React и reduxReact и redux
React и redux
Дмитрий Радыно
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
Simon Willison
 
Angular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd MottoAngular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd Motto
Future Insights
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
psstoev
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
React
React React
React
중운 박
 
Switch to React.js from AngularJS developer
Switch to React.js from AngularJS developerSwitch to React.js from AngularJS developer
Switch to React.js from AngularJS developer
Eugene Zharkov
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Tomasz Bak
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
sitecrafting
 
Promise pattern
Promise patternPromise pattern
Promise pattern
Sebastiaan Deckers
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScript
Deepu S Nath
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with Redux
Vedran Blaženka
 
22 j query1
22 j query122 j query1
22 j query1
Fajar Baskoro
 
React JS and Redux
React JS and ReduxReact JS and Redux
React JS and Redux
Glib Kechyn
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
Dominic Arrojado
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
nishasowdri
 
Intro to ReactJS
Intro to ReactJSIntro to ReactJS
Intro to ReactJS
Harvard Web Working Group
 
Step objects
Step objectsStep objects
Step objects
Tim Sukhachev
 
Angular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd MottoAngular Performance: Then, Now and the Future. Todd Motto
Angular Performance: Then, Now and the Future. Todd Motto
Future Insights
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
psstoev
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Switch to React.js from AngularJS developer
Switch to React.js from AngularJS developerSwitch to React.js from AngularJS developer
Switch to React.js from AngularJS developer
Eugene Zharkov
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Tomasz Bak
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
sitecrafting
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScript
Deepu S Nath
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with Redux
Vedran Blaženka
 
React JS and Redux
React JS and ReduxReact JS and Redux
React JS and Redux
Glib Kechyn
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
nishasowdri
 

Similar to Kakunin E2E framework showcase (20)

Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
Ilia Idakiev
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
Ryunosuke SATO
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
John Ferguson Smart Limited
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
Pavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
Droidcon Berlin
 
Dan Webb Presentation
Dan Webb PresentationDan Webb Presentation
Dan Webb Presentation
RubyOnRails_dude
 
How to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI ComponentsHow to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI Components
cagataycivici
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-ons
Sami Ekblad
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
joshcjensen
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
All Things Open
 
Testable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScriptTestable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScript
Jon Kruger
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
Wildan Maulana
 
jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
chandrashekher786
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Iakiv Kramarenko
 
Backbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 Floripa
Rafael Felix da Silva
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
Ilia Idakiev
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
John Ferguson Smart Limited
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
Pavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
Droidcon Berlin
 
How to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI ComponentsHow to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI Components
cagataycivici
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-ons
Sami Ekblad
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.NativeConnect.js - Exploring React.Native
Connect.js - Exploring React.Native
joshcjensen
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
All Things Open
 
Testable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScriptTestable, Object-Oriented JavaScript
Testable, Object-Oriented JavaScript
Jon Kruger
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Iakiv Kramarenko
 
Ad

More from The Software House (20)

Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
The Software House
 
Uszanowanko Podsumowanko
Uszanowanko PodsumowankoUszanowanko Podsumowanko
Uszanowanko Podsumowanko
The Software House
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?
The Software House
 
O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?
The Software House
 
Chat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon ChimeChat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon Chime
The Software House
 
Migracje danych serverless
Migracje danych serverlessMigracje danych serverless
Migracje danych serverless
The Software House
 
Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?
The Software House
 
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWSAnaliza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
The Software House
 
Feature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScriptFeature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScript
The Software House
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScript
The Software House
 
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQLAutomatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
The Software House
 
Serverless Compose vs hurtownia danych
Serverless Compose vs hurtownia danychServerless Compose vs hurtownia danych
Serverless Compose vs hurtownia danych
The Software House
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięci
The Software House
 
Jak skutecznie read model. Case study
Jak skutecznie read model. Case studyJak skutecznie read model. Case study
Jak skutecznie read model. Case study
The Software House
 
Firestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny KrzemowejFirestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny Krzemowej
The Software House
 
Jak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzachJak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzach
The Software House
 
Jak poskromić AWS?
Jak poskromić AWS?Jak poskromić AWS?
Jak poskromić AWS?
The Software House
 
O łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.jsO łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.js
The Software House
 
Amazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurzeAmazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurze
The Software House
 
Od Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki koduOd Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki kodu
The Software House
 
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
The Software House
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?
The Software House
 
O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?
The Software House
 
Chat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon ChimeChat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon Chime
The Software House
 
Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?
The Software House
 
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWSAnaliza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
The Software House
 
Feature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScriptFeature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScript
The Software House
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScript
The Software House
 
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQLAutomatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
The Software House
 
Serverless Compose vs hurtownia danych
Serverless Compose vs hurtownia danychServerless Compose vs hurtownia danych
Serverless Compose vs hurtownia danych
The Software House
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięci
The Software House
 
Jak skutecznie read model. Case study
Jak skutecznie read model. Case studyJak skutecznie read model. Case study
Jak skutecznie read model. Case study
The Software House
 
Firestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny KrzemowejFirestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny Krzemowej
The Software House
 
Jak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzachJak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzach
The Software House
 
O łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.jsO łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.js
The Software House
 
Amazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurzeAmazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurze
The Software House
 
Od Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki koduOd Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki kodu
The Software House
 
Ad

Recently uploaded (20)

Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 

Kakunin E2E framework showcase

  • 2. ADAM POLAK PHP DEVELOPER JS DEVELOPER E2E DEVELOPER E2E DEVELOPER JS DEVELOPER TOMASZ GÓRSKI
  • 3. KAKUNIN WORKSHOPS AGENDA ▸ HOW TO INSTALL AND CONFIGURE KAKUNIN? ▸ HOW TO NAVIGATE BETWEEN PAGES AND VALIDATE CURRENT PAGE? ▸ HOW TO INTERACT WITH ELEMENTS AND VALIDATE CONTENT? ▸ HOW TO FILL IN, CHECK OUT ITS VALUES AND VALIDATE FORMS? ▸ HOW TO CHECK EMAILS CONTENT? ▸ HOW TO DEBUG KAKUNIN?
  • 4. KAKUNIN WORKSHOPS ▸ HOW TO EXTEND KAKUNIN WITH CUSTOM STEPS? ▸ HOW TO HANDLE NON-BUILT-IN FORM FIELD TYPES? ▸ HOW TO ADD SCENARIO SPECIFIC HOOKS? ▸ HOW TO CONNECT DIFFERENT MAILING SERVICE? AGENDA
  • 6. WHAT IS KAKUNIN? ▸ PROTRACTOR EXTENSION ▸ GHERKIN AS A PROGRAMMING LANGUAGE ▸ BUILT-IN STEPS TO SOLVE MOST COMMON CASES ▸ EASLY EXTENDABLE ▸ HANDLES ANGULAR AND NON-ANGULAR APPS OUT OF THE BOX KAKUNIN
  • 7. WHAT ARE WE GOING TO TEST? KAKUNIN WORKSHOPS
  • 8. INSTALATION HOW TO INSTALL? { "name": "workshop", "version": "0.0.1", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "", "license": "ISC" } cd kakunin-workshop mkdir kakunin-workshop npm init
  • 9. INSTALATION HOW TO INSTALL? npm install webdriver-manager
 npm install protractor
 npm install kakunin { ... "scripts": { ... "kakunin": "NODE_ENV=prod kakunin" }, ... "devDependencies": { ...
 "webdriver-manager": "12.0.6", "protractor": "5.1.2", "kakunin": "1.0.1" } }
  • 10. INSTALATION HOW TO INSTALL? npm run kakunin init cd step_definitions
 ln -s ../node_modules/kakunin/dist/step_definitions/elements.js kakunin-elements.js ln -s ../node_modules/kakunin/dist/step_definitions/debug.js kakunin-debug.js ln -s ../node_modules/kakunin/dist/step_definitions/file.js kakunin-file.js ln -s ../node_modules/kakunin/dist/step_definitions/form.js kakunin-form.js ln -s ../node_modules/kakunin/dist/step_definitions/email.js kakunin-email.js ln -s ../node_modules/kakunin/dist/step_definitions/generators.js kakunin-generators.js ln -s ../node_modules/kakunin/dist/step_definitions/navigation.js kakunin-navigation.js
  • 11. INSTALATION HOW TO INSTALL? npm run kakunin Scenario: If you can see this in console then hook is working properly. ✔ When I visit the "page" page ✔ And I generate random "name" as "myName" ✔ Then my matcher "e:name" matches "v:myName" ✔ And my matcher "e:name" matches "Bob" 1 scenario (1 passed) 4 steps (4 passed) 0m00.757s
  • 12. INSTALATION HOW TO RUN A SINGLE SCENARIO? npm run kakunin -- --tags @someTag npm run kakunin -- --tags="@someTag and @otherTag" npm run kakunin -- --tags="@someTag or @otherTag" npm run kakunin -- --tags="not @someTag"
  • 14. NAVIGATE BETWEEN PAGES PAGE OBJECT const { BasePage } = require('kakunin'); class MainPage extends BasePage { constructor() { super(); this.url = '/'; } } module.exports = new MainPage();
  • 15. NAVIGATE BETWEEN PAGES SCENARIO - NAVIGATING Feature: Load main page Scenario: Load main page as homepage Given/When I visit the "main" page The name of a page object file. For this case there has to be a file "main.js" in pages directory.
  • 16. NAVIGATE BETWEEN PAGES SCENARIO - CHECKING OUT ON WHAT PAGE WE ARE Then the "main" page is displayed The name of a page object file. For this case there has to be a file "main.js" in pages directory.
  • 17. NAVIGATE BETWEEN PAGES SCENARIO - DEBUGGING Give/When/Then I wait for "20" seconds Give/When/Then I pause
  • 18. NAVIGATE BETWEEN PAGES WHAT ABOUT URL WITH PARAMETERS ? /suppliers/some-supplier-id/clients/some-client-id /suppliers/:supplierId/clients/:clientId ... this.url = '/suppliers/:supplierId/clients/:clientId'; ...
  • 19. NAVIGATE BETWEEN PAGES PAGE CONTEXT Then the "main" page is displayed EVERY BUILT-IN STEP (EXCEPT NAVIGATION ONES) WILL HAVE AN ACCESS TO MAIN PAGE OBJECT.
  • 21. INTERACTING WITH ELEMENTS Then the "showActive" element is visible The name of a selector from current page object file. ELEMENT VISIBILITY
  • 22. INTERACTING WITH ELEMENTS SELECTORS ▸ defines access to element ▸ support for protractor locators
 http://www.protractortest.org/#/api? view=ProtractorBy ▸ support for angular only attributes
  • 23. INTERACTING WITH ELEMENTS SELECTORS ▸ id attribute, custom attribute, custom class, unique class - GOOD ▸ for angular app: ng-model, ng-repeat - GOOD ▸ html tag - BAD ▸ angular validation classes (ng-valid, ng-pristine etc) - VERY BAD
  • 24. INTERACTING WITH ELEMENTS SELECTORS this.mySelectorName = $('.css-selector'); this.mySelectorName = $('html-tag'); this.mySelectorName = $('html-tag.css-selector'); this.mySelectorName = element(by.repeater('project in projects'));
  • 25. INTERACTING WITH ELEMENTS Then the "showActive" element is visible ELEMENT VISIBILITY - PROBLEM THE ELEMENT MUST BE VISIBLE RIGHT AWAY. IT DOES NOT WAIT FOR ELEMENT TO BE VISIBLE.
  • 26. INTERACTING WITH ELEMENTS When/Given/Then I wait for "visibilityOf" of the "showActive" element ELEMENT VISIBILITY - SOLUTION uses protractors expected conditions internally, for example visibilityOf invisibilityOf
  • 27. INTERACTING WITH ELEMENTS ELEMENT VISIBILITY - WHAT ELSE? When/Given/Then the "showCompleted" element is present When/Given/Then the "showCompleted" element is not visible When/Given/Then the "showCompleted" element is not present
  • 28. INTERACTING WITH ELEMENTS When I fill the "myForm" form with: | fieldSelector | value to be used | Form selector Input selector this.myForm = $('.add-todo'); this.fieldSelector = $('.add-todo input[name="add-todo"]'); FILLING UP FORM
  • 29. INTERACTING WITH ELEMENTS Then the "myForm" form is filled with: | fieldSelector | value to be used | Form selector Input selector CHECKING OUT FORM VALUE
  • 30. INTERACTING WITH ELEMENTS WHAT ABOUT DIFFERENT FIELD TYPES? ▸ supports all of the basic html field types (radio, checkbox, textarea, select, file, text) ▸ allows to add custom made handlers for field types
  • 31. INTERACTING WITH ELEMENTS HOW ABOUT SUBMITTING ? When I click the "addTodoButton" element The name of a selector from current page object file.
  • 33. CUSTOM STEPS OUR STEP Given I am logged in as an "submitter" User role
  • 34. CUSTOM STEPS CUCUMBER 2.0 - STEP DEFINITION const { defineSupportCode } = require('kakunin'); defineSupportCode(({ Given }) => { Given(/^I am logged in as an "([^"]*)"$/, function (user) { return Promise.resolve(); }); });
  • 35. CUSTOM STEPS ACCESS PAGE FROM CODE const myPage = browser.page.myPage;
  • 36. CUSTOM STEPS BASE PAGE METHODS visit() click(elementSelectorName) isDisabled(elementSelectorName) isPresent(elementSelectorName) isVisible(elementSelectorName) isOn()
  • 37. CUSTOM STEPS BASE PAGE METHODS getNumberOfElements(elementSelectorName) scrollIntoElement(elementSelectorName, optionalIndexForArrayElement)
  • 38. CUSTOM STEPS BASE PAGE METHODS fillForm(formData) [ [ 'fieldSelector', 'fieldValue' ] ] checkForm(formData) [ [ 'fieldSelector', 'fieldValue' ] ]
  • 39. CUSTOM STEPS BASE PAGE METHODS fillField(fieldSelector, fiedlValue) checkField(fieldSelector, fiedlValue) EVERY METHOD RETURNS A PROMISE
  • 40. CUSTOM STEPS USER PROVIDER this.userProvider.getUser(userName); accounts: { userName: { accounts: [ { email: '[email protected]', password: 'somePassword' } ] }
 }
  • 41. CUSTOM STEPS USER PROVIDER this.currentUser = { account: { email: '[email protected]', password: 'somePassword' }, type: "userName" }
  • 43. HOOKS HOOK DEFINITION const { defineSupportCode } = require('kakunin'); defineSupportCode(({ After }) => { After(() => {
 return Promise.resolve();
 }); }); defineSupportCode(({ After }) => { After('@someTag', () => {
 return Promise.resolve();
 }); });
  • 44. HOOKS HOOK DEFINITION - EXECUTE REMOTE JS CODE protractor.browser.executeScript('your js code to be run inside a browser');
  • 45. HOOKS HOOK DEFINITION - CLEAR COOKIES protractor.browser.manage().deletAllCookies();
  • 48. CUSTOM HANDLERS INTERFACE isSatisfiedBy(element, elementName) { return Promise.resolve(); } handleFill(page, elementName, desiredValue) { return Promise.resolve(); } handleCheck(page, elementName, desiredValue) { return Promise.resolve(); } getPriority() { return 1000; }
  • 49. CUSTOM HANDLERS HANDLER SERVICE - ADDING NEW HANDLER const { handlers } = require('kakunin'); class MyHandler {} handler.addHandler(new MyHandler());
  • 50. CUSTOM HANDLERS CUSTOM SELECT HTML <div class="form__field serviceMarket form__field--danger"> <label class="form__label form__label--required">Service Market</label> <div class="Select Select--single is-clearable is-focused is-open"> <div class="Select-control"> </div> <div class="Select-menu-outer"> <div role="listbox" class="Select-menu"> <div style="overflow: visible; width: 0px;"> <div aria-label="grid" class="ReactVirtualized__Grid ReactVirtualized__List VirtualSelectGrid"> <div class="ReactVirtualized__Grid__innerScrollContainer"> <div class="select__option" data-e2e="/app_e2e.php/service_markets/ 80a06089-2f94-4992-8f7c-1d30fc7b8a3e">SME Services</div> </div> </div> </div> </div> </div> </div> </div>
  • 51. CUSTOM HANDLERS CUSTOM SELECT HTML - SELECTED OPTION <div class="form__field serviceMarket"> <label class="form__label form__label--required">Service Market</label> <div class="Select Select--single is-clearable has-value"> <input type="hidden" name="serviceMarket" value="/app_e2e.php/service_markets/ 80a06089-2f94-4992-8f7c-1d30fc7b8a3e"> </div> </div>
  • 53. TRANSFORMERS A WAY TO GENERATE OR TRANSFORM VALUES FROM
 HUMAN READABLE VERSION TO APP USABLE.
  • 55. TRANSFORMERS When I fill the "myForm" form with: | projectUrl | http://some-url.com | | projectType | 1234 | WITHOUT TRANSFORMERS When I fill the "myForm" form with: | projectUrl | g:projectUrl | | projectType | d:projectTypes:website | WITH TRANSFORMERS
  • 56. TRANSFORMERS GENERATORS const { generators } = require('kakunin'); class ProjectUrlGenerator{ isSatisfiedBy(name) { return this.name === 'projectUrl'; } generate(params) { return Promise.resolve('http://some-url.pl'); } } generators.addGenerator(new ProjectUrlGenerator());
  • 57. TRANSFORMERS DICTIONARIES const { dictionaries } = require('kakunin'); class ProjectTypesDictionary{ constructor() { this.values = { 'myServiceMarket':'/service_markets/80a06089-2f94-4992-8f7c-1d30fc7b8a3e' }; this.name = 'projectTypes'; } isSatisfiedBy(name) { return this.name === name; } getMappedValue(key) { return this.values[key]; } } dictionaries.addDictionary(new ProjectTypesDictionary());
  • 59. EMAILS CONFIGURATION email: { type: 'mailtrap', config: { apiKey: '81279e9fb9351ebdf7aefef89e6a5701', inboxId: '203459', url: 'https://mailtrap.io/api/v1' } }, clearEmailInboxBeforeTests: true mailer_host: smtp.mailtrap.io mailer_user: efb44191c15785 mailer_password: 821a734f231165 mailer_port: 2525 mailer_default_from: [email protected]
  • 60. EMAILS CHECKING EMAILS Then the email has been sent: | currentUser | | | | | subject | some subject | | | | html_body | some id | | | | file | some file | PDF | 9000 | ALLOWS TO FILTER EMAIL CONTENT BY MULTIPLE FILEDS
  • 61. EMAILS CHECKING EMAILS - FILTERS ▸ currentUser - checks if email was sent to current logged user, requires integration with Kakunin User Provider ▸ subject - allows to check email subject ▸ html_body - allows to check content of email ▸ file - allows to check attachments, it's type, name and size ALL FILTERS SUPPORT MATCHERS
  • 63. REGULAR EXPRESSIONS CUSTOM REGEX module.exports = { matchingStoreId: '(STORE-[0-9]{6}-[0-9]{4})', emailSubject: '(Join Our Store - STORE-[0-9]{6}-[0-9]{4}‫اﻟﯿﻨﺎ‬ ‫اﻧﻀﻢ‬ -)' }; USAGE r:matchingStoreId
  • 65. CONTENT VALIDATION FORM VALIDATIONS Then the error messages should be displayed: | element | errorMessage | | nameValidationMsg | This value should not be blank. | | targetMarketSegmentValidationMsg | This value should not be blank. | this.nameValidationMsg = $('.name .form__error');
  • 66. CONTENT VALIDATION VALIDATE ELEMENT CONTENT Then there are "equal 1" "todos" elements uses chai.js expectations equal X above X between X Y at least X
  • 67. CONTENT VALIDATION VALIDATE ELEMENT CONTENT Then there are "equal 1" "todos" elements REQUIRES LIST SELECTOR
  • 68. CONTENT VALIDATION VALIDATE ELEMENT CONTENT Then there are "equal 1" "todos" elements this.todos = $$('ul li'); this.todos = element.all(by.css('ul li'));
  • 69. CONTENT VALIDATION VALIDATE ELEMENT CONTENT Then there is element "myElement" with value "r:notEmpty" Then there is element "myElement" with value "t:some text" Then there is element "myElement" with value "f:isClickable"
  • 71. ALLOW TO VALIDATE FILED VALUE, BUT ALSO BEHAVIOUR (FOR EXAMPLE IF ELEMENT IS
 CLICKABLE) CONTENT VALIDATION
  • 72. CUSTOM MATCHER const { matchers } = require('kakunin'); class MyMatcher { isSatisfiedBy(prefix, name) { return prefix === 'm:' && name === 'pending'; } match(protractorElement, matcherName) { return protractorElement.getText().then((value) => value === 'pending'); } } matchers.addMatcher(new MyMatcher()); CONTENT VALIDATION
  • 73. CONTENT VALIDATION VALIDATE ELEMENT CONTENT - DETAILED CHECK Then there are "equal 1" following elements for element "todos": | element | value | | removeButton | f:isVisible | REQUIRES LIST SELECTOR CHILD ELEMENTS MUST BE LOCATORS, NOT ELEMENTS
  • 74. CONTENT VALIDATION this.todos = $$('ul li'); Then there are "equal 1" following elements for element "todos": | element | value | | removeButton | f:isVisible | this.removeButton = by.css('.remove'); VALIDATE ELEMENT CONTENT - DETAILED CHECK
  • 76. CONTENT VALIDATION FILE DOWNLOAD Then the file "fileName.extension" should be downloaded downloaded file name, the same as the one normally have in browser
  • 77. CONTENT VALIDATION FILE DOWNLOAD - CLEAR DOWNLOAD DIRECTORY @downloadClearAfter @downloadClearBefore