├── .gitignore ├── .jshintrc ├── .travis.yml ├── Contributing.md ├── LICENSE ├── Readme.md ├── docs ├── attributeMatches.md ├── elementHasChildren.md ├── elementHasChildrenCount.md ├── elementHasNoChildren.md ├── jqueryClick.md ├── jqueryElement.md ├── jqueryElementNotPresent.md ├── jqueryElementPresent.md ├── saveElementScreenshot.md ├── setSelect2Data.md ├── setSelect2Value.md ├── setValueAndTrigger.md ├── shell.md ├── urlMatch.md ├── waitForAttribute.md ├── waitForDocumentLoaded.md ├── waitForJqueryAjaxRequest.md ├── waitForJqueryElement.md ├── waitForText.md └── waitForTitle.md ├── es6 ├── assertions │ ├── attributeMatches.js │ ├── elementHasChildren.js │ ├── elementHasChildrenCount.js │ ├── elementHasNoChildren.js │ ├── jqueryElementNotPresent.js │ ├── jqueryElementPresent.js │ └── urlMatch.js ├── commands │ ├── jqueryClick.js │ ├── jqueryElement.js │ ├── saveElementScreenshot.js │ ├── setSelect2Data.js │ ├── setSelect2Value.js │ ├── setValueAndTrigger.js │ ├── shell.js │ ├── waitForAttribute.js │ ├── waitForDocumentLoaded.js │ ├── waitForJqueryAjaxRequest.js │ ├── waitForJqueryElement.js │ ├── waitForText.js │ └── waitForTitle.js ├── getElementFromSelector.js └── getMultipleSelectors.js ├── gulpfile.js ├── js ├── assertions │ ├── attributeMatches.js │ ├── elementHasChildren.js │ ├── elementHasChildrenCount.js │ ├── elementHasNoChildren.js │ ├── jqueryElementNotPresent.js │ ├── jqueryElementPresent.js │ └── urlMatch.js └── commands │ ├── jqueryClick.js │ ├── jqueryElement.js │ ├── saveElementScreenshot.js │ ├── setSelect2Data.js │ ├── setSelect2Value.js │ ├── setValueAndTrigger.js │ ├── shell.js │ ├── waitForAttribute.js │ ├── waitForDocumentLoaded.js │ ├── waitForJqueryAjaxRequest.js │ ├── waitForJqueryElement.js │ ├── waitForText.js │ └── waitForTitle.js ├── package.json ├── runTests.sh ├── tests ├── html │ ├── ajax.html │ ├── ajax.json │ ├── attribute.html │ ├── children.html │ ├── input.html │ ├── jqueryClick.html │ ├── jqueryElement.html │ ├── nochildren.html │ ├── pageObjects.html │ ├── screenshot.html │ ├── select2.html │ ├── text.html │ ├── title.html │ ├── urlMatch.html │ ├── waitForDocumentLoaded.html │ └── waitForJqueryElement.html ├── mockserver-netty-3.9.17-jar-with-dependencies.jar ├── nightwatch.conf.js ├── page_objects │ └── test.js ├── runTests.js └── setMocks.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tests/mockserver.log 3 | tests/mockserver_request.log 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true 3 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: false 3 | language: node_js 4 | node_js: 5 | - "12" 6 | 7 | addons: 8 | firefox: latest 9 | 10 | env: 11 | - NIGHTWATCH_ENV= 12 | - NIGHTWATCH_ENV=chrome 13 | 14 | matrix: 15 | allow_failures: 16 | - env: "NIGHTWATCH_ENV=chrome" 17 | 18 | before_install: 19 | - "export DISPLAY=:99.0" 20 | - "sh -e /etc/init.d/xvfb start" 21 | - sleep 3 22 | - jdk_switcher use oraclejdk8 23 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | So, you want to add you command or assertion. Great! 4 | 5 | Read [this guide](http://nightwatchjs.org/guide#extending) on how to write it. 6 | The name you give to the file will be the name of the command or assertion. 7 | 8 | Then: 9 | 10 | - checkout the repository 11 | - start writing your command in the `es6/commands` folder or your assertion in the `es6/assertions` folder 12 | - run `npm install -g gulp` 13 | - run `npm install` in the root folder 14 | - run `gulp` 15 | - make a pull request 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Max Galbusera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## Nightwatch custom commands and assertions 2 | 3 | [![Build Status](https://travis-ci.org/maxgalbu/nightwatch-custom-commands-assertions.svg?branch=master)](https://travis-ci.org/maxgalbu/nightwatch-custom-commands-assertions) [![npm version](https://badge.fury.io/js/nightwatch-custom-commands-assertions.svg)](http://badge.fury.io/js/nightwatch-custom-commands-assertions) 4 | 5 | These are some commands and assertion I use when I'm testing with nightwatch.js and selenium. 6 | 7 | ### How to use these things? 8 | 9 | You can install it using npm: 10 | 11 | ``` 12 | npm install nightwatch-custom-commands-assertions --save-dev 13 | ``` 14 | 15 | Then, open the nightwatch.json file in your editor (or [create it if it doesn't exist](http://nightwatchjs.org/guide#settings-file)) and edit the `custom_commands_path` and `custom_assertions_path` keys so they look like this: 16 | 17 | ```json 18 | { 19 | ... //your config 20 | 21 | "custom_commands_path" : "node_modules/nightwatch-custom-commands-assertions/js/commands", 22 | "custom_assertions_path" : "node_modules/nightwatch-custom-commands-assertions/js/assertions", 23 | 24 | ... //your config again 25 | } 26 | ``` 27 | 28 | Now you should be able to use these commands/assertions when you call `nightwatch --test`. 29 | 30 | ### Alternative ways of installing 31 | 32 | - Go into your `tests` folder (or where your nightwatch.json is) and do: 33 | 34 | ``` 35 | git clone https://github.com/maxgalbu/nightwatch-custom-commands-assertions.git 36 | ``` 37 | 38 | - Download the zipped repository [here](https://github.com/maxgalbu/nightwatch-custom-commands-assertions/archive/master.zip) and extract it wherever you want 39 | 40 | You then need to open your nightwatch.json and edit `custom_commands_path` and `custom_assertions_path` according to where you cloned or extracted the repository. 41 | 42 | 43 | ### Contributing 44 | 45 | See [Contributing.md](https://github.com/maxgalbu/nightwatch-custom-commands-assertions/blob/master/Contributing.md). 46 | 47 | ### List of commands 48 | 49 | See [the docs folder](https://github.com/maxgalbu/nightwatch-custom-commands-assertions/blob/master/docs) 50 | -------------------------------------------------------------------------------- /docs/attributeMatches.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Assert that the element identified by the selector has an attribute that matches 6 | the provided regexp. 7 | ### Examples: 8 | 9 | browser 10 | .url("http://www.github.com") 11 | .assert.attributeMatches("body", "class", /body-class/g) 12 | 13 | browser 14 | .url("http://www.github.com") 15 | .assert.attributeMatches("body", "class", new RegExp("body-class", "g") 16 | 17 | Author: maxgalbu 18 | 19 | ### Params: 20 | 21 | * **String** *selector* - the element selector 22 | * **String** *attribute* - the element attribute 23 | * **RegExp** *regexp* - the regexp that should match the attribute 24 | * **String** *[msg]* - output to identify the assertion 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/elementHasChildren.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Assert that the element identified by the selector has children nodes 6 | that matches the children selectors (if passed) 7 | ### Examples: 8 | 9 | browser 10 | .url("http://www.github.com") 11 | .assert.elementHasChildren("#list-of-tasks", "div, span") 12 | 13 | browser 14 | .url("http://www.github.com") 15 | .assert.elementHasChildren("#list-of-tasks", ".myclass, li input:checked") 16 | 17 | Author: maxgalbu 18 | 19 | ### Params: 20 | 21 | * **String** *selector* - the element selector 22 | * **String** *[children_selectors]* - a list of selectors for children nodes 23 | * **String** *[msg]* - output to identify the assertion 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/elementHasChildrenCount.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Assert that the element identified by the selector has a number of children nodes 6 | that match the children selectors (if passed) 7 | ### Examples: 8 | 9 | browser 10 | .url("http://www.github.com") 11 | .assert.elementHasChildrenCount("#list-of-tasks", 10) 12 | 13 | browser 14 | .url("http://www.github.com") 15 | .assert.elementHasChildrenCount("#list-of-tasks", 1, ".myclass, li input:checked") 16 | 17 | Author: maxgalbu 18 | 19 | ### Params: 20 | 21 | * **String** *selector* - the element selector 22 | * **Integer** *children_count* - number of elements that should match 23 | * **String** *[children_selectors]* - a list of selectors for children nodes 24 | * **String** *[msg]* - output to identify the assertion 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/elementHasNoChildren.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Assert that the element identified by the selector doesn't have children nodes 6 | ### Examples: 7 | 8 | browser 9 | .url("http://www.github.com") 10 | .assert.elementHasNoChildren("#list-of-tasks") 11 | 12 | Author: maxgalbu 13 | 14 | ### Params: 15 | 16 | * **String** *selector* - the element selector 17 | * **String** *[msg]* - output to identify the assertion 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/jqueryClick.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Clicks an element using jquery selectors. 6 | ### Examples: 7 | 8 | browser.jqueryClick(".classname:first > input:checked") 9 | browser.jqueryClick("div:has(.classname):contains('something'):last") 10 | 11 | Author: maxgalbu 12 | 13 | ### Params: 14 | 15 | * **String** *selector* - jQuery selector for the element 16 | * **Function** *[callback]* - function that will be called after the element is clicked 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/jqueryElement.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Returns an element using jquery selectors 6 | ### Examples: 7 | 8 | browser.jqueryElement(".classname:first > input:checked", function(element) { 9 | //element is the DOM element 10 | }) 11 | browser.jqueryElement("div:has(.classname):contains('something'):last", function(element) { 12 | //element is the DOM element 13 | }) 14 | 15 | Author: maxgalbu 16 | 17 | ### Params: 18 | 19 | * **String** *selector* - jQuery selector for the element 20 | * **Function** *callback* - function that will be called with the element as argument 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/jqueryElementNotPresent.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | assert that the element identified by the jquery selector does NOT exist in the DOM. 6 | ***Requires jqueryElement command*** 7 | ### Examples: 8 | 9 | browser 10 | .url("http://www.github.com") 11 | .assert.jqueryElementNotPresent("div:eq(10000)") 12 | 13 | Author: maxgalbu 14 | 15 | ### Params: 16 | 17 | * **String** *selector* - jQuery selector 18 | * **String** *[msg]* - output to identify the assertion 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/jqueryElementPresent.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Assert that the element identified by the jquery selector exists in the DOM. 6 | ***Requires jqueryElement command*** 7 | ### Examples: 8 | 9 | browser 10 | .url("http://www.github.com") 11 | .assert.jqueryElementPresent("div:eq(2)") 12 | 13 | Author: maxgalbu 14 | 15 | ### Params: 16 | 17 | * **String** *selector* - jQuery selector 18 | * **String** *[msg]* - output to identify the assertion 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/saveElementScreenshot.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Take a screenshot of the requested element 6 | 7 | This command requires ImageMagick installed on the system and node-easyimage installed as a npm module. You can install node-easyimage with: 8 | 9 | npm install --production 10 | 11 | And imagemagick with: 12 | 13 | #Centos 14 | yum install ImageMagick 15 | 16 | #OSX 17 | brew install imagemagick --build-from-source 18 | 19 | #Ubuntu 20 | apt-get install ImageMagick 21 | ### Examples: 22 | 23 | browser.saveElementScreenshot(".class", "screenshot-name.jpg"); 24 | 25 | Author: maxgalbu 26 | 27 | ### Params: 28 | 29 | * **String** *elementSelector* - css/xpath selector for the element 30 | * **Function** *fileName* - file path where the screenshot is saved 31 | * **String** *[defaultMessage]* - message to display 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /docs/setSelect2Data.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Set a select2 value using select2("data", object) 6 | ### Examples: 7 | 8 | browser.setSelect2Data("input[type=hidden].has-select2", {id:1, text: "hello"}) 9 | 10 | Author: maxgalbu 11 | 12 | ### Params: 13 | 14 | * **String** *selector* - jQuery selector for the select2 input/select2 15 | * **Object** *data* - data of the element to be set (see the example) 16 | * **Function** *[callback]* - function that will be called after the element's value has been set 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/setSelect2Value.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Set a select2 value using select2("value", string/number) 6 | ### Examples: 7 | 8 | browser.setSelect2Value("select.has-select2:hidden", "some value") 9 | 10 | Author: maxgalbu 11 | 12 | ### Params: 13 | 14 | * **String** *selector* - jQuery selector for the select2 input/select2 15 | * **Mixed** *value* - value of the element to be set 16 | * **Function** *[callback]* - function that will be called after the element's value has been set 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/setValueAndTrigger.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Set a value on an `` or a `` or a `` or a ` 14 | 17 | 18 | -------------------------------------------------------------------------------- /tests/html/jqueryClick.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 |
14 |
15 |
16 | 17 | 18 |
19 | 20 | google 21 | 22 | -------------------------------------------------------------------------------- /tests/html/jqueryElement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 | 10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /tests/html/nochildren.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 |
9 | some text 10 |
11 | 12 | -------------------------------------------------------------------------------- /tests/html/pageObjects.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 |
18 |
19 |
20 | 21 | 22 |
23 | 24 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/html/screenshot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |

Title

8 | 9 |
10 | 13 |
14 | View on GitHub 15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |

Browser Automation

23 |

24 | Nightwatch.js is an easy to use Node.js based End-to-End (E2E) testing solution for browser based apps and websites. 25 |

26 |

27 | It uses the powerful Selenium WebDriver API to perform commands and assertions on DOM elements. 28 |

29 |
30 |
31 |

Main Features

32 |
    33 |
  • 34 |

    35 | 36 | Simple but powerful syntax which enables you to write tests very quickly, using only Javascript and CSS selectors. 37 |

    38 |
  • 39 | 40 |
  • 41 |

    42 | 43 | Built-in command-line test runner which can run the tests either sequentially or in parallel, together, by group or single. 44 |

    45 |
  • 46 | 47 |
  • 48 |

    49 | 50 | Manages the Selenium server automatically; can be disabled if Selenium runs on another host. 51 |

    52 |
  • 53 | 54 |
  • 55 |

    56 | 57 | Works with cloud testing providers, such as SauceLabs and BrowserStack. 58 |

    59 |
  • 60 | 61 |
  • 62 |

    63 | 64 | Continous Integration support: JUnit XML reporting is built-in so you can integrate your tests in your build process with systems such as Teamcity, Jenkins, Hudson etc. 65 |

    66 |
  • 67 | 68 |
  • 69 |

    70 | 71 | Use CSS selectors or Xpath to locate and verify elements on the page or execute commands. 72 |

    73 |
  • 74 | 75 |
  • 76 |

    77 | 78 | Easy to extend to implement your application specific commands. 79 |

    80 |
  • 81 |
82 |
83 |
84 | 85 |
86 | 87 | -------------------------------------------------------------------------------- /tests/html/select2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/html/text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 |
14 | something 15 |
16 | 17 | -------------------------------------------------------------------------------- /tests/html/title.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | something 4 | 5 | 6 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/html/urlMatch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | test urlMatch 4 | 5 | -------------------------------------------------------------------------------- /tests/html/waitForDocumentLoaded.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test wait for document loaded 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/html/waitForJqueryElement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 |
14 |
15 |
16 | 17 |
18 | 19 | -------------------------------------------------------------------------------- /tests/mockserver-netty-3.9.17-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxgalbu/nightwatch-custom-commands-assertions/b69066df0a8b2794b7bd0d9d08725986913a6427/tests/mockserver-netty-3.9.17-jar-with-dependencies.jar -------------------------------------------------------------------------------- /tests/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | var seleniumServer = require('selenium-server'); 2 | 3 | module.exports = { 4 | "src_folders": "runTests.js", 5 | "output_folder": false, 6 | "custom_commands_path": "../js/commands", 7 | "custom_assertions_path": "../js/assertions", 8 | "page_objects_path": "./page_objects", 9 | 10 | "selenium": { 11 | "start_process": true, 12 | "server_path": seleniumServer.path, 13 | "log_path": false, 14 | "host": "127.0.0.1", 15 | "port": 4444, 16 | "cli_args": { 17 | "webdriver.gecko.driver": "../node_modules/geckodriver/bin/geckodriver", 18 | "webdriver.chrome.driver": "../node_modules/chromedriver/lib/chromedriver/chromedriver", 19 | "webdriver.ie.driver": "" 20 | } 21 | }, 22 | 23 | "test_settings": { 24 | "default": { 25 | "launch_url": "http://localhost", 26 | "selenium_port" : 4444, 27 | "selenium_host" : "localhost", 28 | "silent": true, 29 | "screenshots": { 30 | "enabled": false, 31 | "path": "" 32 | }, 33 | "desiredCapabilities": { 34 | "browserName": "firefox", 35 | "javascriptEnabled": true, 36 | "acceptSslCerts": true 37 | } 38 | }, 39 | 40 | "chrome": { 41 | "desiredCapabilities": { 42 | "browserName": "chrome", 43 | "chromeOptions" : { 44 | "args": ["no-sandbox"] 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/page_objects/test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | elements: { 3 | thirdDiv: 'div:nth-child(3)', 4 | thatButton: 'div:eq(2) #button', 5 | waitForCss: { 6 | selector: '#div', 7 | locateStrategy: "css", 8 | }, 9 | waitForXpath: { 10 | selector: '//div[@id="div"]', 11 | locateStrategy: "xpath", 12 | }, 13 | }, 14 | sections: { 15 | menu: { 16 | selector: '#navbar', 17 | elements: { 18 | homeButton: '.homebutton', 19 | otherButton: '.otherbutton' 20 | } 21 | }, 22 | jqueryClick: { 23 | selector: "body", 24 | elements: { 25 | element: 'div:eq(2) button' 26 | } 27 | }, 28 | select2: { 29 | selector: "body", 30 | elements: { 31 | element: '#select2' 32 | } 33 | }, 34 | trigger: { 35 | selector: "body", 36 | elements: { 37 | element: '#textinput' 38 | } 39 | }, 40 | children: { 41 | selector: "body", 42 | elements: { 43 | element: '.myclass', 44 | element2: 'li' 45 | } 46 | }, 47 | jqueryWait: { 48 | selector: ".myclass:eq(2)", 49 | elements: { 50 | element: ' > #div:visible' 51 | } 52 | } 53 | } 54 | }; -------------------------------------------------------------------------------- /tests/runTests.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var easyimg = require("easyimage"); 3 | var baseurl = "http://localhost:9999"; 4 | 5 | module.exports = { 6 | "test page objects": function(browser) { 7 | var pageObject = browser.page.test(); 8 | 9 | browser.url(baseurl+"/pageObjects"); 10 | pageObject 11 | .jqueryClick("@thatButton") 12 | .assert.visible("#div") 13 | .assert.elementHasChildren("@thirdDiv"); 14 | 15 | //Test using css selector 16 | browser.url(baseurl+"/waitForText"); 17 | pageObject.waitForText("@waitForCss", function (text) { 18 | return text === "something else"; 19 | }); 20 | 21 | //test using xpath selector 22 | browser.url(baseurl+"/waitForText"); 23 | pageObject.waitForText("@waitForXpath", function (text) { 24 | return text === "something else"; 25 | }); 26 | 27 | //Test using css selector 28 | browser.url(baseurl+"/waitForAttribute"); 29 | pageObject.waitForAttribute("@waitForCss", "class", function (divclass) { 30 | return divclass === "myclass"; 31 | }); 32 | 33 | //test using xpath selector 34 | browser.url(baseurl+"/waitForAttribute"); 35 | pageObject.waitForAttribute("@waitForXpath", "class", function (divclass) { 36 | return divclass === "myclass"; 37 | }); 38 | 39 | //test if locatestrategy is restored correctly 40 | browser.url(baseurl+"/waitForText"); 41 | browser.waitForText("#div", function (text) { 42 | return text === "something else"; 43 | }); 44 | 45 | browser.end(); 46 | }, 47 | 48 | "test page objects with sections": function(browser) { 49 | var pageObject = browser.page.test(); 50 | 51 | browser.url(baseurl+"/jqueryClick"); 52 | pageObject.section.jqueryClick.jqueryClick("@element"); 53 | browser.assert.visible("#div"); 54 | 55 | browser.url(baseurl+"/setSelect2Data"); 56 | pageObject.section.select2.setSelect2Data("@element", {id:1, text:"ciao"}); 57 | browser.assert.value("input[name=select2]", "1"); 58 | 59 | browser.url(baseurl+"/setSelect2Value"); 60 | pageObject.section.select2.setSelect2Value("@element", "1"); 61 | browser.assert.value("input[name=select2]", "1"); 62 | 63 | browser.url(baseurl+"/setValueAndTrigger"); 64 | pageObject.section.trigger.setValueAndTrigger("@element", "1"); 65 | browser.assert.visible("#div"); 66 | 67 | browser.url(baseurl+"/children"); 68 | pageObject.section.children 69 | .assert.elementHasChildren("@element") 70 | .assert.elementHasChildren("@element", "li") 71 | .assert.elementHasChildren("@element", "@element2"); 72 | 73 | browser.url(baseurl+"/nochildren"); 74 | pageObject.section.children 75 | .assert.elementHasNoChildren("@element") 76 | .assert.elementHasNoChildren("@element"); 77 | 78 | browser.url(baseurl+"/waitForJqueryElement"); 79 | pageObject.section.jqueryWait 80 | .waitForJqueryElement("@element"); 81 | 82 | browser.end(); 83 | }, 84 | 85 | "test elementHasChildren": function(browser) { 86 | return browser 87 | .url(baseurl+"/children") 88 | .assert.elementHasChildren(".myclass") 89 | .assert.elementHasChildren(".myclass", "li") 90 | .end(); 91 | }, 92 | 93 | "test elementHasChildrenCount": function(browser) { 94 | return browser 95 | .url(baseurl+"/children") 96 | .assert.elementHasChildrenCount(".myclass", 3) 97 | .assert.elementHasChildrenCount(".myclass", 3, "li") 98 | .end(); 99 | }, 100 | 101 | "test elementHasNoChildren": function(browser) { 102 | return browser 103 | .url(baseurl+"/nochildren") 104 | .assert.elementHasNoChildren(".myclass") 105 | .assert.elementHasNoChildren(".text") 106 | .end(); 107 | }, 108 | 109 | "test saveElementScreenshot": function(browser) { 110 | var imageFileName = "test.png"; 111 | 112 | return browser 113 | .url(baseurl+"/saveElementScreenshot") 114 | .saveElementScreenshot(".jumbotron", imageFileName) 115 | .perform(function(client, done) { 116 | easyimg.info(imageFileName).then(function(imageInfo) { 117 | client.assert.equal(imageInfo.height, 234, "saveElementScreenshot works (height found ()"+imageInfo.height+") should be 234)"); 118 | fs.unlinkSync(imageFileName); 119 | done(); 120 | }); 121 | }) 122 | .end(); 123 | }, 124 | 125 | "test waitForJqueryElement": function(browser) { 126 | browser.globals.waitForConditionTimeout = 5000; 127 | 128 | return browser 129 | .url(baseurl+"/waitForJqueryElement") 130 | .waitForJqueryElement(".myclass:eq(2) > #div:visible", function() { 131 | client.assert.equal(true, true, "waitForJqueryElement works"); 132 | }) 133 | .end(); 134 | }, 135 | 136 | "test waitForAttribute": function(browser) { 137 | browser.globals.waitForConditionTimeout = 5000; 138 | 139 | return browser 140 | .url(baseurl+"/waitForAttribute") 141 | .waitForAttribute("#div", "class", function (divclass) { 142 | return divclass === "myclass"; 143 | }) 144 | .end(); 145 | }, 146 | 147 | "test waitForText": function(browser) { 148 | browser.globals.waitForConditionTimeout = 5000; 149 | 150 | return browser 151 | .url(baseurl+"/waitForText") 152 | .waitForText("#div", function (text) { 153 | return text === "something else"; 154 | }) 155 | .url(baseurl+"/waitForText") 156 | .useXpath() 157 | .waitForText("//div[@id='div']", function (text) { 158 | return text === "something else"; 159 | }) 160 | .useCss() 161 | .end(); 162 | }, 163 | 164 | "test waitForTitle": function(browser) { 165 | browser.globals.waitForConditionTimeout = 5000; 166 | 167 | return browser 168 | .url(baseurl+"/waitForTitle") 169 | .waitForTitle(function(title) { 170 | return title === "something else"; 171 | }) 172 | .end(); 173 | }, 174 | 175 | "test urlMatch": function(browser) { 176 | return browser 177 | .url(baseurl+"/urlMatch") 178 | .assert.urlMatch(/tch$/) 179 | .assert.urlMatch(/\/[a-zA-z]+$/) 180 | .end(); 181 | }, 182 | 183 | "test jqueryElementPresent": function(browser) { 184 | return browser 185 | .url(baseurl+"/jqueryElementPresent") 186 | .assert.jqueryElementPresent(".myclass:has(button)") 187 | .end(); 188 | }, 189 | 190 | "test jqueryElementNotPresent": function(browser) { 191 | return browser 192 | .url(baseurl+"/jqueryElementPresent") 193 | .assert.jqueryElementNotPresent(".noclass") 194 | .end(); 195 | }, 196 | 197 | "test jqueryClick": function(browser) { 198 | return browser 199 | .url(baseurl+"/jqueryClick") 200 | .jqueryClick("div:eq(2) button") 201 | .assert.visible("#div") 202 | .jqueryClick("a") 203 | .pause(1000) 204 | .assert.urlMatch(/github/) 205 | .end(); 206 | }, 207 | 208 | "test jqueryElement": function(browser) { 209 | return browser 210 | .url(baseurl+"/jqueryElement") 211 | .jqueryElement(".myclass:has(button)", function(element) { 212 | this.assert.equal(!!element, true, "jqueryElement: element found"); 213 | }) 214 | .jqueryElement(".nonexistingclass:eq(10)", function(element) { 215 | this.assert.equal(!element, true, "jqueryElement: element not found"); 216 | }) 217 | .end(); 218 | }, 219 | 220 | "test setSelect2Data": function(browser) { 221 | return browser 222 | .url(baseurl+"/setSelect2Data") 223 | .setSelect2Data("#select2", {id:1, text:"ciao"}) 224 | .assert.value("input[name=select2]", "1") 225 | .end(); 226 | }, 227 | 228 | "test setSelect2Value": function(browser) { 229 | return browser 230 | .url(baseurl+"/setSelect2Value") 231 | .setSelect2Value("#select2", "1") 232 | .assert.value("input[name=select2]", "1") 233 | .end(); 234 | }, 235 | 236 | "test setValueAndTrigger": function(browser) { 237 | return browser 238 | .url(baseurl+"/setValueAndTrigger") 239 | .setValueAndTrigger("#textinput", "1") 240 | .pause(200) 241 | .assert.visible("#div") 242 | .end(); 243 | }, 244 | 245 | "test waitForJqueryAjaxRequest": function(browser) { 246 | return browser 247 | .url(baseurl+"/waitForAjaxRequest") 248 | .waitForJqueryAjaxRequest(5000) 249 | .assert.containsText("#div", "something else") 250 | .end(); 251 | }, 252 | 253 | "test waitForDocumentLoaded": function (browser) { 254 | return browser 255 | .url(baseurl + "/waitForDocumentLoaded") 256 | .waitForDocumentLoaded(5000) 257 | .assert.visible("#xkcd-img") 258 | .end(); 259 | }, 260 | }; 261 | -------------------------------------------------------------------------------- /tests/setMocks.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | mockServer = require('mockserver-client'), 3 | mockServerClient = mockServer.mockServerClient; 4 | 5 | function monkeyPatch(mockSrvClnt) 6 | { 7 | mockSrvClnt.mockHTMLResponse = function(uri, filePath, options) { 8 | if (!options) { 9 | options = {}; 10 | } 11 | 12 | if (!fs.existsSync(filePath)) { 13 | console.log("File doesn't exist: "+filePath); 14 | return; 15 | } 16 | 17 | var params = { 18 | httpRequest: { 19 | method: 'GET', 20 | path: uri, 21 | }, 22 | httpResponse: { 23 | statusCode: 200, 24 | body: fs.readFileSync(filePath, {encoding: "utf8"}), 25 | headers: [{ 26 | name: "Content-Type", 27 | values: ["text/html; charset=utf-8"] 28 | }], 29 | }, 30 | times: { 31 | unlimited: true 32 | } 33 | }; 34 | 35 | if (options.delay) { 36 | params.httpResponse.delay = { 37 | timeUnit: 'MILLISECONDS', 38 | value: options.delay 39 | }; 40 | } 41 | 42 | mockSrvClnt.mockAnyResponse(params); 43 | }; 44 | 45 | return mockSrvClnt; 46 | } 47 | 48 | monkeyPatchedMSC = monkeyPatch(mockServerClient("localhost", 9999)); 49 | monkeyPatchedMSC.mockHTMLResponse('/pageObjects', "html/pageObjects.html"); 50 | monkeyPatchedMSC.mockHTMLResponse('/urlMatch', "html/urlMatch.html"); 51 | monkeyPatchedMSC.mockHTMLResponse('/jqueryClick', "html/jqueryClick.html"); 52 | monkeyPatchedMSC.mockHTMLResponse('/jqueryElement', "html/jqueryElement.html"); 53 | monkeyPatchedMSC.mockHTMLResponse('/jqueryElementPresent', "html/jqueryElement.html"); 54 | monkeyPatchedMSC.mockHTMLResponse('/setSelect2Data', "html/select2.html"); 55 | monkeyPatchedMSC.mockHTMLResponse('/setSelect2Value', "html/select2.html"); 56 | monkeyPatchedMSC.mockHTMLResponse('/setValueAndTrigger', "html/input.html"); 57 | monkeyPatchedMSC.mockHTMLResponse('/waitForJqueryElement', "html/waitForJqueryElement.html"); 58 | monkeyPatchedMSC.mockHTMLResponse('/waitForAttribute', "html/attribute.html"); 59 | monkeyPatchedMSC.mockHTMLResponse('/waitForText', "html/text.html"); 60 | monkeyPatchedMSC.mockHTMLResponse('/waitForTitle', "html/title.html"); 61 | monkeyPatchedMSC.mockHTMLResponse('/saveElementScreenshot', "html/screenshot.html"); 62 | monkeyPatchedMSC.mockHTMLResponse('/children', "html/children.html"); 63 | monkeyPatchedMSC.mockHTMLResponse('/nochildren', "html/nochildren.html"); 64 | monkeyPatchedMSC.mockHTMLResponse('/waitForAjaxRequest', "html/ajax.html"); 65 | monkeyPatchedMSC.mockHTMLResponse('/delayedAjax', "html/ajax.json", { 66 | delay: 3000 67 | }); 68 | monkeyPatchedMSC.mockHTMLResponse('/waitForDocumentLoaded', "html/waitForDocumentLoaded.html"); 69 | --------------------------------------------------------------------------------