Merge pull request #4242 from MaximKhlobystov/selenium-multiremote
[HTML5 Client] Multiple browser sessions in test specs
This commit is contained in:
commit
50efdf3066
@ -1,91 +0,0 @@
|
||||
# Acceptance Testing in HTML Client. Getting Started
|
||||
|
||||
The test suite for HTML5 client is currently under active development. The following instructions will help you install all the necessary tools and libraries to run the exiting specs and start writing your own tests.
|
||||
|
||||
## Run Selenium Server
|
||||
|
||||
Assuming that you have the BigBlueButton repository in `/home/firstuser/dev`, navigate to the directory containing acceptance tests:
|
||||
```sh
|
||||
$ cd /home/firstuser/dev/bigbluebutton/bigbluebutton-html5/tests/webdriverio
|
||||
```
|
||||
|
||||
Now, you should navigate to the `tools` directory inside `webdriverio`. This folder will store all the Selenium- and browser-related third-party files that you need to download.
|
||||
|
||||
Download Selenium jar file:
|
||||
```sh
|
||||
$ curl -O http://selenium-release.storage.googleapis.com/3.4/selenium-server-standalone-3.4.0.jar
|
||||
```
|
||||
|
||||
and browser-specific WebDriver server.
|
||||
|
||||
Firefox WebDriver (GeckoDriver):
|
||||
```sh
|
||||
$ curl -L https://github.com/mozilla/geckodriver/releases/download/v0.16.1/geckodriver-v0.16.1-linux64.tar.gz | tar xz
|
||||
```
|
||||
|
||||
Chrome WebDriver (ChromeDriver):
|
||||
```sh
|
||||
$ wget https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip
|
||||
$ unzip chromedriver_linux64.zip
|
||||
```
|
||||
|
||||
Along with the WebDriver, you need to install the browser itself.
|
||||
|
||||
How to install Chrome:
|
||||
```sh
|
||||
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
||||
$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install google-chrome-stable
|
||||
```
|
||||
|
||||
How to install Firefox:
|
||||
```sh
|
||||
$ wget sourceforge.net/projects/ubuntuzilla/files/mozilla/apt/pool/main/f/firefox-mozilla-build/firefox-mozilla-build_53.0.3-0ubuntu1_amd64.deb
|
||||
$ sudo dpkg -i firefox-mozilla-build_53.0.3-0ubuntu1_amd64.deb
|
||||
```
|
||||
|
||||
In order to run headless browser, we will use Xvfb display server:
|
||||
```sh
|
||||
$ sudo apt-get install xvfb
|
||||
```
|
||||
|
||||
At this point, you can run the Selenium server (replace `./geckodriver` with `./chromedriver` if you use Chrome):
|
||||
```sh
|
||||
$ xvfb-run java -jar selenium-server-standalone-3.4.0.jar
|
||||
```
|
||||
|
||||
If you get an error `Xvfb failed to start`, run it with an `-a` option (Xvfb will use another display if the current one is already in use):
|
||||
```sh
|
||||
$ xvfb-run -a java -jar selenium-server-standalone-3.4.0.jar
|
||||
```
|
||||
|
||||
Congratulations! You have Selenium server up and running. It is ready to handle your test cases. Now, keep the `xvfb-run` process running and continue in a new terminal session.
|
||||
|
||||
## Run the test specs
|
||||
|
||||
We use WebdriverIO interface to write the acceptance test cases. In order to execute the existing tests, you need to use `wdio` test runner. By default, it will look into any `*.spec.js` file inside the `/home/firstuser/dev/bigbluebutton/bigbluebutton-html5/tests/webdriverio/specs` directory. You can change the location of the test specs by modifying the `wdio` config file: `wdio.conf.js` (inside the `webdriverio` directory).
|
||||
|
||||
Before proceeding any further, make sure HTML5 client is up and running.
|
||||
Node.js installation is also required:
|
||||
|
||||
```sh
|
||||
$ sudo apt-get install nodejs-legacy
|
||||
```
|
||||
|
||||
You can run all of the existing test specs with a single npm command:
|
||||
|
||||
```sh
|
||||
$ cd /home/firstuser/dev/bigbluebutton/bigbluebutton-html5
|
||||
$ npm run test
|
||||
```
|
||||
|
||||
### Test suites
|
||||
|
||||
To make it easier to run a single specific set of tests, we group the specs into test suits. All the suits are defined in `wdio.conf.js`.
|
||||
|
||||
To run a single test suite, you need to pass its name to the npm script:
|
||||
```sh
|
||||
$ npm run test -- --suite login
|
||||
```
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
let Page = require('./page');
|
||||
let pageObject = new Page();
|
||||
let chai = require('chai');
|
||||
|
||||
class LandingPage extends Page {
|
||||
open() {
|
||||
@ -13,28 +14,48 @@ class LandingPage extends Page {
|
||||
}
|
||||
|
||||
get url() {
|
||||
return 'http://localhost:8080/demo/demoHTML5.jsp';
|
||||
return `${browser.baseUrl}/demo/demoHTML5.jsp`;
|
||||
}
|
||||
|
||||
get username() {
|
||||
return $('input[name=username]');
|
||||
// Username input field on the HTML5 client's landing page:
|
||||
|
||||
get usernameInputSelector() {
|
||||
return 'input[name=username]';
|
||||
}
|
||||
|
||||
get joinButton() {
|
||||
return $('input[type=submit]');
|
||||
get usernameInputElement() {
|
||||
return $(this.usernameInputSelector);
|
||||
}
|
||||
|
||||
// Submit button on the HTML5 client's landing page:
|
||||
|
||||
get joinButtonSelector() {
|
||||
return 'input[type=submit]';
|
||||
}
|
||||
|
||||
get joinButtonElement() {
|
||||
return $(this.joinButtonSelector);
|
||||
}
|
||||
|
||||
// Home page:
|
||||
|
||||
get loadedHomePageSelector() {
|
||||
return '#app';
|
||||
}
|
||||
|
||||
get loadedHomePageElement() {
|
||||
return $('#app');
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
joinWithButtonClick() {
|
||||
this.joinButton.click();
|
||||
this.joinButtonElement.click();
|
||||
}
|
||||
|
||||
joinWithEnterKey() {
|
||||
pageObject.pressEnter();
|
||||
}
|
||||
|
||||
get loadedHomePage() {
|
||||
return $('#app');
|
||||
}
|
||||
}
|
||||
|
||||
// To use in the future tests that will require login
|
||||
|
@ -6,7 +6,7 @@ class Page {
|
||||
}
|
||||
|
||||
pressEnter() {
|
||||
browser.keys('Enter');
|
||||
chromeBrowser.keys('Enter');
|
||||
}
|
||||
|
||||
isFirefox() {
|
||||
|
@ -2,20 +2,28 @@
|
||||
|
||||
let LandingPage = require('../pageobjects/landing.page');
|
||||
let chai = require('chai');
|
||||
let utils = require('../utils');
|
||||
|
||||
describe('Landing page', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000; // default value is 10000
|
||||
});
|
||||
|
||||
it('should have correct title', function () {
|
||||
LandingPage.open();
|
||||
chai.expect(browser.getTitle()).to.equal(LandingPage.title);
|
||||
utils.assertTitle(LandingPage.title);
|
||||
});
|
||||
|
||||
it('should allow user to login if the username is specified and the Join button is clicked',
|
||||
function () {
|
||||
LandingPage.open();
|
||||
LandingPage.username.waitForExist();
|
||||
LandingPage.username.setValue('Maxim');
|
||||
|
||||
chromeBrowser.setValue(LandingPage.usernameInputSelector, 'Maxim');
|
||||
firefoxBrowser.setValue(LandingPage.usernameInputSelector, 'Anton');
|
||||
|
||||
LandingPage.joinWithButtonClick();
|
||||
LandingPage.loadedHomePage.waitForExist(5000);
|
||||
LandingPage.loadedHomePageElement.waitForExist(5000);
|
||||
});
|
||||
|
||||
it('should not allow user to login if the username is not specified (login using a button)',
|
||||
@ -29,29 +37,27 @@ describe('Landing page', function () {
|
||||
browser.pause(5000); // amount of time we usually wait for the home page to appear
|
||||
|
||||
// verify that we are still on the landing page
|
||||
chai.expect(browser.getUrl()).to.equal(LandingPage.url);
|
||||
utils.assertUrl(LandingPage.url);
|
||||
});
|
||||
|
||||
if (!LandingPage.isFirefox()) {
|
||||
it('should allow user to login if the username is specified and then Enter key is pressed',
|
||||
function () {
|
||||
function () { // Chrome-only
|
||||
LandingPage.open();
|
||||
LandingPage.username.waitForExist();
|
||||
LandingPage.username.setValue('Maxim');
|
||||
|
||||
chromeBrowser.setValue(LandingPage.usernameInputSelector, 'Maxim');
|
||||
LandingPage.joinWithEnterKey();
|
||||
LandingPage.loadedHomePage.waitForExist(5000);
|
||||
chromeBrowser.waitForExist(LandingPage.loadedHomePageSelector, 5000);
|
||||
});
|
||||
|
||||
it('should not allow user to login if the username is not specified (login using Enter key)',
|
||||
function () {
|
||||
function () { // Chrome-only
|
||||
LandingPage.open();
|
||||
|
||||
// we intentionally don't enter username here
|
||||
|
||||
LandingPage.joinWithEnterKey();
|
||||
browser.pause(5000); // amount of time we usually wait for the gome page to appear
|
||||
chai.expect(browser.getUrl()).to.equal(LandingPage.url);
|
||||
chromeBrowser.pause(5000); // amount of time we usually wait for the gome page to appear
|
||||
chai.expect(browser.getUrl().chromeBrowser).to.equal(LandingPage.url);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
19
bigbluebutton-html5/tests/webdriverio/utils.js
Normal file
19
bigbluebutton-html5/tests/webdriverio/utils.js
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
let chai = require('chai');
|
||||
|
||||
class Utils {
|
||||
assertTitle(title) {
|
||||
browser.remotes.forEach(function(browserName) {
|
||||
chai.expect(browser.select(browserName).getTitle()).to.equal(title);
|
||||
});
|
||||
}
|
||||
assertUrl(url) {
|
||||
browser.remotes.forEach(function(browserName) {
|
||||
chai.expect(browser.getUrl()[browserName]).to.equal(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Utils();
|
||||
|
@ -1,10 +1,17 @@
|
||||
exports.config = {
|
||||
specs: ['tests/webdriverio/specs/**/*.spec.js'],
|
||||
capabilities: [
|
||||
{
|
||||
browserName: 'chrome',
|
||||
capabilities: {
|
||||
chromeBrowser: {
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
}
|
||||
},
|
||||
],
|
||||
firefoxBrowser: {
|
||||
desiredCapabilities: {
|
||||
browserName: 'firefox'
|
||||
}
|
||||
}
|
||||
},
|
||||
baseUrl: 'http://localhost:8080',
|
||||
framework: 'jasmine',
|
||||
reporters: ['spec', 'junit'],
|
||||
@ -19,5 +26,10 @@ exports.config = {
|
||||
'tests/webdriverio/specs/login.spec.js',
|
||||
],
|
||||
},
|
||||
before: function() {
|
||||
// make the properties that browsers share and the list of browserNames available:
|
||||
browser.remotes = Object.keys(exports.config.capabilities);
|
||||
browser.baseUrl = exports.config.baseUrl;
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user