First you need to have Node.JS installed, go to nodejs.org for more about Node.JS
Once you have Node installed, you can install MSL Server from npm to start launching your app locally!
npm install msl-server
./node_modules/msl-server/bin/msl [options]
npm install -g msl-server
msl [options]
msl --basedir=./msl-sample-app --port=8001 --debug=true
Next, you can install the client that will be used to interact with the server. The client is used to set up the mock responses for the requests that will be made by your application running locally on the server. The client is also used to tell the server which requests to intercept for validation. MSL currently supports 3 clients with more language bindings coming soon.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css">
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
<!-- include msl browser client -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/msl-client-browser/1.0.6/mockapi-browser.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/msl-client-browser/1.0.6/appcontainer-driver.min.js"></script>
<!-- include jquery library and spec files here-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="spec/MSLTestSpec.js"></script>
</head>
<body>
</body>
</html>
describe('Example suite', function() {
var callbackFunc = function (req, responseText) {
return '[' + responseText + ']';
}
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
beforeEach(function(done) {
// Load app inside iframe
openApp('http://localhost:8001/msl-sample-app/index.html');
setTimeout(function() {
done();
}, 200);
});
afterEach(function() {
unRegisterMock('localhost', 8001, "");
});
it('Test for register and get mock response', function(done) {
// Use msl-client to set mock response
var mockResponse = {};
mockResponse.requestPath = '/services/getlanguages';
mockResponse.responseText = '[{"label":"apache"},{"label":"apple"}]';
mockResponse.statusCode = 200;
mockResponse.delayTime = 0;
setMockRespond('localhost', 8001, mockResponse);
// Type into first input field which triggers a REST call to return a JSON response
getElement('#autocomplete').val('a');
getElement('#autocomplete').keydown();
setTimeout(function() {
// Validate the drop down is display correctly with mock response
expect(getElement('ul li:nth-of-type(1)').text()).toBe('apache');
expect(getElement('ul li:nth-of-type(2)').text()).toBe('apple');
// Click on the Second item from the drop down
getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').click();
// Validate that correct item was selected
expect(getElement('#autocomplete').val()).toBe('apple');
done();
}, 500);
});
it('Test for register and get mock response using function', function(done) {
// Use msl-client to set mock response
var mockResponse = {};
mockResponse.requestPath = '/services/getlanguages';
mockResponse.responseText = '{"label":"apache"},{"label":"apple"}';
mockResponse.eval = callbackFunc;
mockResponse.statusCode = 200;
mockResponse.delayTime = 0;
setMockRespond('localhost', 8001, mockResponse);
// Type into first input field which triggers a REST call to return a JSON response
getElement('#autocomplete').val('a');
getElement('#autocomplete').keydown();
setTimeout(function() {
// Validate the drop down is display correctly with mock response
expect(getElement('ul li:nth-of-type(1)').text()).toBe('apache');
expect(getElement('ul li:nth-of-type(2)').text()).toBe('apple');
// Click on the Second item from the drop down
getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').click();
// Validate that correct item was selected
expect(getElement('#autocomplete').val()).toBe('apple');
done();
}, 500);
});
it('Test setup mock response with template', function(done) {
// Registering the template that will be used for the response
registerTemplate('localhost', 8001,
'[{"label":"{{param1}}"},{"label":"{{param2}}"}]', 'example');
// Set up the object that contains our response configuration
var configurations = {};
configurations.requestPath = '/services/getlanguages';
configurations.contentType = 'application/json';
configurations.id = 'example';
configurations.keyValues = {
'param1': 'Boat',
'param2': 'Cat'
};
configurations.statusCode = 200;
configurations.delayTime = 0;
// Use msl-client to set mock response
setMockRespond('localhost', 8001, configurations);
// Type into first input field which triggers a REST call to return a JSON response
getElement('#autocomplete').val('b');
getElement('#autocomplete').keydown();
setTimeout(function() {
// Validate the drop down is display correctly with mock response using template
expect(getElement('ul li:nth-of-type(1)').text()).toBe('Boat');
expect(getElement('ul li:nth-of-type(2)').text()).toBe('Cat');
// Click on the first item from the drop down
getElement('.ui-autocomplete .ui-menu-item:nth-of-type(1)').click();
// Validate that correct item was selected
expect(getElement('#autocomplete').val()).toBe('Boat');
done();
}, 500);
});
it('Test XHR intercept, Get method', function(done) {
// Use msl-client to register intercept
setInterceptXHR('localhost', 8001, '/services/getservice');
// Type into second input field and click GET button which triggers a GET request
getElement('#getInput').val('testGet');
getElement('#getRequest').click();
// Retrieve intercepted XHR and validate correct GET request was made by the app
getInterceptedXHR('localhost', 8001, '/services/getservice', function(resp) {
var intrReq = JSON.parse(resp).xhr_1;
expect(intrReq.xhr.url).toBe('/services/getservice?term=testGet');
expect(intrReq.xhr.method).toBe('GET');
});
done();
});
it('Test XHR intercept, Post method', function(done) {
// Use msl-client to register intercept
setInterceptXHR('localhost', 8001, '/services/postservice');
// Type into second input field and click GET button which triggers a GET request
getElement('#output-box').val('testPost');
getElement('#postRequest').click();
setTimeout(function() {
// Retrieve intercepted XHR and validate correct POST request was made by the app
getInterceptedXHR('localhost', 8001, '/services/postservice', function(resp) {
var intrReq = JSON.parse(resp).xhr_1;
var regex = new RegExp('timestamp=\\d*&text=testPost');
expect(intrReq.xhr.url).toBe('/services/postservice');
expect(regex.test(intrReq.post)).toBe(true);
expect(intrReq.xhr.method).toBe('POST');
});
done();
}, 500);
});
it('Test for setting the delay time of returning a mock response', function(done) {
// Use msl-client to set mock response
var mockResponse = {};
mockResponse.requestPath = '/services/getlanguages';
mockResponse.responseText = '[{"label":"apache"},{"label":"apple"}]';
mockResponse.statusCode = 200;
mockResponse.delayTime = 3000;
setMockRespond('localhost', 8001, mockResponse);
// Type into first input field which triggers a REST call to return a JSON response
getElement('#autocomplete').val('a');
getElement('#autocomplete').keydown();
setTimeout(function() {
// Validate that the response is delayed
expect(getElement('.ui-autocomplete .ui-menu-item:nth-of-type(1)').size()).toBe(0);
expect(getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').size()).toBe(0);
}, 500);
setTimeout(function() {
// Validate the drop down is display correctly with mock response
expect(getElement('ul li:nth-of-type(1)').text()).toBe('apache');
expect(getElement('ul li:nth-of-type(2)').text()).toBe('apple');
// Click on the Second item from the drop down
getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').click();
// Validate that correct item was selected
expect(getElement('#autocomplete').val()).toBe('apple');
done();
}, 3500);
});
it('Test unRegisterMock function', function(done) {
// Use msl-client to set mock response
var mockResponse = {};
mockResponse.requestPath = '/services/getlanguages';
mockResponse.responseText = '[{"label":"Ice Cream"},{"label":"Candy"}]';
mockResponse.statusCode = 200;
mockResponse.delayTime = 0;
setMockRespond('localhost', 8001, mockResponse);
// Type into first input field which triggers a REST call to return a JSON response
getElement('#autocomplete').val('I');
getElement('#autocomplete').keydown();
setTimeout(function() {
// Click on the first item from the drop down
expect(getElement('ul li:nth-of-type(1)').text()).toBe('Ice Cream');
expect(getElement('ul li:nth-of-type(2)').text()).toBe('Candy');
getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').click();
setTimeout(function() {
// Validate that correct item was selected
expect(getElement('#autocomplete').val()).toBe('Candy');
// Reload Page
openApp('http://localhost:8001/msl-sample-app/index.html');
setTimeout(function() {
unRegisterMock('localhost', 8001, '/services/getlanguages');
getElement('#autocomplete').val('I');
expect(getElement('.ui-autocomplete .ui-menu-item:nth-of-type(2)').size()).toBe(0);
done();
}, 200);
}, 500);
}, 500);
});
it('Test mocking POST ajax success', function(done) {
// Use msl-client to set mock response
setMockRespond('localhost', 8001, {"requestPath":"/services/postservice", "responseText":'{"outputBoxValue":"hello"}'});
// Type hellomsl on text area and click POST button
getElement('#output-box').val('hellomsl');
getElement('#postRequest').click();
setTimeout(function() {
// Validate that postResult span is populated with the text 'hello' which was the success call from the ajax call
expect(getElement('#postResult').text()).toBe('hello');
done();
}, 500);
});
});
POM Snippet:
<dependency>
<groupId>org.finra.msl</groupId>
<artifactId>msl-client-java</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.finra.jtaf</groupId>
<artifactId>jtaf-extwebdriver</artifactId>
<version>1.4</version>
</dependency>
package org.finra.msl.client;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.finra.jtaf.ewd.ExtWebDriver;
import org.finra.jtaf.ewd.session.SessionManager;
import org.finra.jtaf.ewd.widget.element.Element;
import org.finra.jtaf.ewd.widget.element.InteractiveElement;
import org.finra.msl.client.MockAPI;
import org.finra.msl.client.MockAPI.XHR;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
/**
* Tests for msl-client-java and msl-server
*/
public class MockAPITest {
public static ExtWebDriver ewd;
@BeforeClass
public static void setUp() throws Exception {
// Get a new ExtWebDriver session
ewd = SessionManager.getInstance().getNewSession();
}
@Before
public void openApp() {
// Open the test application
ewd.open("http://localhost:8001/msl-sample-app/index.html");
}
@Test
public void testTextResponse() throws Exception {
// Create object for autocomplete element
InteractiveElement autocomplete = new InteractiveElement(".//*[@id=\"autocomplete\"]");
// Set up the object that contains our response configuration
Map configurations = new HashMap();
configurations.put("requestPath", "/services/getlanguages");
configurations.put("responseText", "{\"label\":\"Java\"},{\"label\":\"Perl\"}");
configurations.put("contentType", "application/json");
configurations.put("eval",
"function (req,responseText) { return '[' + responseText + ']'; }");
configurations.put("statusCode", "200");
configurations.put("delayTime", "0");
// Setting up the mock response using the configuration
MockAPI.setMockRespond("localhost", 8001, configurations);
// Triggering the event
autocomplete.type("J");
Element dropdown = new Element(".//ul[contains(@class, \"ui-autocomplete\")]");
dropdown.waitForVisible();
// Getting all of the options from the dropdown menu to be validated
List elements = ewd.findElements(By
.xpath(".//ul[contains(@class, \"ui-autocomplete\")]/li"));
// Verify that the options are from the mocked response
Assert.assertEquals("Java", elements.get(0).getText());
Assert.assertEquals("Perl", elements.get(1).getText());
}
@Test
public void testTemplateResponse() throws Exception {
MockAPI.registerTemplate("localhost", 8001,
"[{\"label\":\"{{param1}}\"},{\"label\":\"{{param2}}\"}]", "example");
InteractiveElement autocomplete = new InteractiveElement(".//*[@id=\"autocomplete\"]");
Map configurations = new HashMap();
configurations.put("requestPath", "/services/getlanguages");
configurations.put("contentType", "application/json");
configurations.put("statusCode", "200");
configurations.put("delayTime", "0");
Map keyValue = new HashMap();
keyValue.put("param1", "German");
keyValue.put("param2", "English");
configurations.put("keyValues", keyValue);
configurations.put("id", "example");
// Setting up the mock response using the configuration
MockAPI.setMockRespond("localhost", 8001, configurations);
// Triggering the event
autocomplete.type("J");
Element dropdown = new Element(".//ul[contains(@class, \"ui-autocomplete\")]");
dropdown.waitForVisible();
// Getting all of the options from the dropdown menu to be validated
List elements = ewd.findElements(By
.xpath(".//ul[contains(@class, \"ui-autocomplete\")]/li"));
// Verify that the options are from the mocked response
Assert.assertEquals("German", elements.get(0).getText());
Assert.assertEquals("English", elements.get(1).getText());
}
@Test
public void testGetIntercept() throws Exception {
MockAPI.setInterceptXHR("localhost", 8001, "/services/getservice");
InteractiveElement input = new InteractiveElement(".//*[@id=\"getInput\"]");
input.type("GET Example");
InteractiveElement button = new InteractiveElement(".//*[@id=\"getRequest\"]");
button.click();
// Due to WebDriver operating too quickly sometimes, it is held up so
// that the web-server has enough time to intercept
Thread.sleep(5);
// Get the HTTP requests that have been intercepted
XHR[] interceptedXHR = MockAPI.getInterceptedXHR("localhost", 8001, "/services/getservice");
// Verify that the intercepted HTTP request is the one we are looking
// for by checking its content
Assert.assertEquals("GET", interceptedXHR[0].getMethodType());
Assert.assertEquals("/services/getservice?term=GET+Example", interceptedXHR[0].getUrl());
Assert.assertEquals("GET Example", interceptedXHR[0].getQueryString().get("term"));
}
@Test
public void testPostIntercept() throws Exception {
// Setting
MockAPI.setInterceptXHR("localhost", 8001, "/services/postservice");
InteractiveElement input = new InteractiveElement(".//*[@id=\"output-box\"]");
input.type("POST Example");
InteractiveElement button = new InteractiveElement(".//*[@id=\"postRequest\"]");
button.click();
// Due to WebDriver operating too quickly sometimes, it is held up so
// that the web-server has enough time to intercept
Thread.sleep(5);
// Get the HTTP requests that have been intercepted
XHR[] interceptedXHR = MockAPI
.getInterceptedXHR("localhost", 8001, "/services/postservice");
// Verify that the intercepted HTTP request is the one we are looking
// for by checking its content
Assert.assertEquals("POST", interceptedXHR[0].getMethodType());
Assert.assertEquals("/services/postservice", interceptedXHR[0].getUrl());
Assert.assertTrue(interceptedXHR[0].getBody().contains("timestamp="));
Assert.assertTrue(interceptedXHR[0].getBody().contains("text=POST+Example"));
}
@Test
public void testUnRegisterMock() throws Exception {
// Create object for autocomplete element
InteractiveElement autocomplete = new InteractiveElement(".//*[@id=\"autocomplete\"]");
// Set up the object that contains our response configuration
Map configurations = new HashMap();
configurations.put("requestPath", "/services/getlanguages");
configurations.put("responseText", "[{\"label\":\"Java\"},{\"label\":\"Perl\"}]");
configurations.put("contentType", "application/json");
configurations.put("statusCode", "200");
configurations.put("delayTime", "0");
// Set up the response using the configuration that was just created
MockAPI.setMockRespond("localhost", 8001, configurations);
// Type into the autocomplete to trigger the event
autocomplete.type("J");
Element dropdown = new Element(".//ul[contains(@class, \"ui-autocomplete\")]");
dropdown.waitForVisible();
List elements = ewd.findElements(By
.xpath(".//ul[contains(@class, \"ui-autocomplete\")]/li"));
autocomplete.getWebElement().clear();
// Verify the dropdown elements
Assert.assertEquals("Java", elements.get(0).getText());
Assert.assertEquals("Perl", elements.get(1).getText());
// Unregister this request so web-server.js no longer responds to it
MockAPI.unRegisterMock("localhost", 8001, "/services/getlanguages");
// Trigger event again
autocomplete.type("J");
// Verify that the dropdown no longer appears now that there
// is no response
Assert.assertEquals(false, !dropdown.isElementPresent());
}
@AfterClass
public static void tearDown() {
ewd.close();
}
}
npm install msl-client
var msl = require('msl-client');
To demonstrate how the msl-client works, an example test has been provided using the sample application that can be obtained from the GitHub project. This example registers responses using text and
a template, validates intercepted requests, and unregisters a mock when it is no longer needed.
// This allows for the use of the msl-client API
var msl = require('msl-client');
var assert = require("assert"),
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer,
webdriver = require('selenium-webdriver');
var server = new SeleniumServer('./selenium-server-standalone-2.39.0.jar', {
port : 4444
});
server.start();
describe('Running Selenium tests', function () {
var client;
this.timeout(50000);
var callbackFunc = function (req, responseText) {
return '[' + responseText + ']';
}
before(function () {
// Builds the webdriver before the tests start.
client = new webdriver.Builder().
usingServer(server.address()).
withCapabilities(webdriver.Capabilities.chrome()).build();
});
beforeEach(function (done) {
// Navigate to the URL for each test and wait for the autocomplete to be present
client.get('http://localhost:8001/msl-sample-app/index.html');
var element = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]'));
element.getText().then(function () {
done();
});
});
after(function (done) {
// After the tests are done, the webdriver is killed
client.quit().then(function () {
done();
});
});
it('The dropdown should appear and contain the mocked data', function (done) {
// Set up the object that contains our response configuration
var configurations = {};
configurations.requestPath = "/services/getlanguages";
configurations.responseText = '{"label":"Java"},{"label":"Perl"}';
configurations.contentType = "application/json";
configurations.eval = callbackFunc.toString();
configurations.statusCode = 200;
configurations.delayTime = 0;
// Setting up the mock response using the configuration
msl.setMockRespond("localhost", 8001, configurations);
// Triggering the event
var autocomplete = client.findElement(webdriver.By.xpath('.//*[@id="autocomplete"]'));
client.executeScript("$('#autocomplete').val('J')");
client.executeScript("$('#autocomplete').keydown()");
// Wait for the dropdown elements to appear
client.wait(function () {
return client.isElementPresent(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
}, 500);
// Get the elements from the dropdown to check the values
var optionOne = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
var optionTwo = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[2]'));
// Verify that the options are from the mocked response
optionOne.getText().then(function (title) {
assert.equal("Java", title);
});
optionTwo.getText().then(function (title) {
assert.equal("Perl", title);
done();
});
});
it('The dropdown should appear and contain the template data', function (done) {
// Registering the template that will be used for the response
msl.registerTemplate('localhost', 8001,
'[{"label":"{{param1}}"},{"label":"{{param2}}"}]', 'example');
// Set up the object that contains our response configuration
var configurations = {};
configurations.requestPath = "/services/getlanguages";
configurations.contentType = "application/json";
configurations.id = "example";
configurations.keyValues = {
"param1" : "German",
"param2" : "English"
};
configurations.statusCode = 200;
configurations.delayTime = 0;
// Setting up the mock response using the configuration
msl.setMockRespond("localhost", 8001, configurations);
// Triggering the event
var autocomplete = client.findElement(webdriver.By.xpath('.//*[@id="autocomplete"]'));
client.executeScript("$('#autocomplete').val('JA')");
client.executeScript("$('#autocomplete').keydown()");
// Wait for the dropdown elements to appear
client.wait(function () {
return client.isElementPresent(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
}, 500);
// Get the elements from the dropdown to check the values
var optionOne = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
var optionTwo = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[2]'));
// Verify that the options are from the mocked response
optionOne.getText().then(function (title) {
assert.equal("German", title);
});
optionTwo.getText().then(function (title) {
assert.equal("English", title);
done();
});
});
it('Testing validation of get requests', function (done) {
// Set up the callback function that will be called when the intercepted http requests
// are retrieved to validate the data
var getValidation = function (responseText) {
var response = JSON.parse(responseText);
var body = response.xhr_1;
assert.equal(body.xhr.url, '/services/getservice?term=GET+Example');
assert.equal(body.xhr.method, 'GET');
done();
}
// Registering the request path that http requests will be intercepted for
msl.setInterceptXHR("localhost", 8001, "/services/getservice");
// Triggering the event
client.executeScript("$('#getInput').val('GET Example')");
client.executeScript("$('#getRequest').click()");
// Pausing and then retrieving all of the intercepted http requests before validating
setTimeout(function () {
msl.getInterceptedXHR("localhost", 8001, "/services/getservice", getValidation);
}, 500);
});
it('Testing validation of post requests', function (done) {
// Set up the callback function that will be called when the intercepted http requests
// are retrieved to validate the data
var postValidation = function (responseText) {
var response = JSON.parse(responseText);
var body = response.xhr_1;
var regex = new RegExp("timestamp=\\d*&text=POST\\+Example");
assert.equal(body.xhr.url, '/services/postservice');
assert.equal(true, regex.test(body.post));
assert.equal(body.xhr.method, 'POST');
done();
}
// Registering the request path that http requests will be intercepted for
msl.setInterceptXHR("localhost", 8001, "/services/postservice");
// Triggering the event
client.executeScript("$('#output-box').val('POST Example')");
client.executeScript("$('#postRequest').click()");
// Pausing and then retrieving all of the intercepted http requests before validating
setTimeout(function () {
msl.getInterceptedXHR("localhost", 8001, "/services/postservice", postValidation);
}, 500);
});
it('Testing unRegisterMock', function (done) {
// Set up the object that contains our response configuration
var configurations = {};
configurations.requestPath = "/services/getlanguages";
configurations.responseText = '[{"label":"French"},{"label":"Spanish"}]';
configurations.contentType = "application/json";
configurations.statusCode = 200;
configurations.delayTime = 0;
// Setting up the mock response using the configuration
msl.setMockRespond("localhost", 8001, configurations);
// Triggering the event
var autocomplete = client.findElement(webdriver.By.xpath('.//*[@id="autocomplete"]'));
client.executeScript("$('#autocomplete').val('JA')");
client.executeScript("$('#autocomplete').keydown()");
// Wait for the dropdown to appear
client.wait(function () {
return client.isElementPresent(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
}, 5000);
// Getting the first element from the list
var optionOne = client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]'));
// Verify that the options are from the mocked response and then unregistering that mock
optionOne.getText().then(function (title) {
assert.equal("French", title);
msl.unRegisterMock("localhost", 8001, "/services/getlanguages");
// Used to remove focus from the input to make sure dropdown disappears
client.executeScript("$('#autocomplete').blur()");
});
// Triggering the event again
client.executeScript("$('#autocomplete').val('J')");
client.executeScript("$('#autocomplete').keydown()");
// Validating that the first element is now no longer present
client.findElement(webdriver.By.xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]')).
then(function (element) {
element.isDisplayed().then(function (displayed) {
assert.equal(false, displayed);
done();
});
});
});
});
pip install .
import mslclient
An example test has been provided along with the client and setup script as a guide on how it can be used and to see how it performs. Like the others, this test uses the sample application located on the
GitHub page and works by registering responses using text and a template, validates intercepted requests, and unregisters a mock
when it is no longer needed.
import mslclient
import unittest
import time
import json
import re
from selenium import webdriver
class TestSequenceFunctions(unittest.TestCase):
@classmethod
def setUpClass(self):
'''Used to create the webdriver instance and open the page to be used for testing
before any test are started.
'''
global chrome
chrome = webdriver.Chrome()
chrome.get("http://localhost:8001/msl-sample-app/index.html")
def test_textResponse(self):
'''This tests the setMockRespond method using a string and a javascript function to set up
the format of the string.
'''
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = chrome.find_element_by_id('autocomplete')
autocomplete.clear()
chrome.find_element_by_id('postRequest').click()
time.sleep(1)
# Setup all of the needed data like request path, the response, function
# for formatting, etc.
configurations = {}
configurations["requestPath"] = "/services/getlanguages"
configurations["responseText"] = "{\"label\":\"Java\"},{\"label\":\"Perl\"}"
configurations["contentType"] = "application/json"
configurations["eval"] = "function (req,responseText) { return '[' + responseText + ']'; }"
configurations["statusCode"] = "200"
configurations["delayTime"] = "0"
# Actually make the call to register this information.
mslclient.setMockRespond("localhost", "8001", configurations)
# Trigger event that fires off request.
autocomplete.send_keys('J')
time.sleep(1)
# Grab the dropdown elements and validate the data against the registered response.
elementOne = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]')
elementTwo = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[2]')
assert elementOne.get_attribute("textContent") == 'Java'
assert elementTwo.get_attribute("textContent") == 'Perl'
def test_templateResponse(self):
'''This tests the setMockRespond method using a template
the format of the string.
'''
# Register the template that will be used later with the key-value pairs.
mslclient.registerTemplate("localhost", "8001",
"[{\"label\":\"{{param1}}\"},{\"label\":\"{{param2}}\"}]", "example")
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = chrome.find_element_by_id('autocomplete')
autocomplete.clear()
chrome.find_element_by_id('postRequest').click()
time.sleep(1)
# Setup all of the needed data like request path, key-value pairs, and template id.
configurations = {}
configurations["requestPath"] = "/services/getlanguages"
configurations["contentType"] = "application/json"
configurations["statusCode"] = "200"
configurations["delayTime"] = "0"
# The values that are to replace the keys in the registered template.
keyVals = {}
keyVals["param1"] = "German"
keyVals["param2"] = "English"
configurations["keyValues"] = keyVals
configurations["id"] = "example"
# Actually make the call to register this information.
mslclient.setMockRespond("localhost", "8001", configurations)
# Trigger event that fires off request.
autocomplete.send_keys('J')
time.sleep(1)
# Grab the dropdown elements and validate the data against the registered response.
elementOne = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]')
elementTwo = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[2]')
assert elementOne.get_attribute("textContent") == 'German'
assert elementTwo.get_attribute("textContent") == 'English'
autocomplete.clear()
def test_getIntercepted(self):
'''This tests the ability to intercept, and validate intercepted, get requests. '''
# Register the request path of the get request to be intercepted
mslclient.setInterceptXHR("localhost", "8001", "/services/getservice")
# Put text into input box which will be added to get request
inputBox = chrome.find_element_by_id('getInput')
inputBox.send_keys('GET Example')
# Trigger the get request
postButton = chrome.find_element_by_id('getRequest')
postButton.click()
time.sleep(1)
# Retrieve all request intercepted that have the provided request path
intercepted = json.loads(mslclient.getInterceptedXHR("localhost", "8001", "/services/getservice"))
# Validate the method and url of the intercepted request
req1 = intercepted['xhr_1']
assert req1['xhr']['method'] == 'GET'
assert req1['xhr']['url'] == '/services/getservice?term=GET+Example'
assert req1['post'] is None
def test_postIntercepted(self):
'''This tests the ability to intercept, and validate intercepted, post requests.'''
# Register the request path of the post request to be intercepted
mslclient.setInterceptXHR("localhost", "8001", "/services/postservice")
# Put text into input box which will be added to post request
inputBox = chrome.find_element_by_id('output-box')
inputBox.send_keys('POST Example')
# Trigger the post request
postButton = chrome.find_element_by_id('postRequest')
postButton.click()
time.sleep(1)
# Retrieve all request intercepted that have the provided request path
intercepted = json.loads(mslclient.getInterceptedXHR("localhost", "8001", "/services/postservice"))
# Validate the method and url of the intercepted request
req1 = intercepted['xhr_1']
assert req1['xhr']['method'] == 'POST'
assert req1['xhr']['url'] == '/services/postservice'
matched = re.match('timestamp=\\d*&text=POST\+Example', req1['post'])
assert matched.group(0) is not None
assert matched.group(0) == req1['post']
def test_unRegisterMock(self):
'''This is used to test unregistering a request path.'''
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = chrome.find_element_by_id('autocomplete')
autocomplete.clear()
chrome.find_element_by_id('postRequest').click()
time.sleep(1)
# Setup all of the needed data like request path, the response, function
# for formatting, etc.
configurations = {}
configurations["requestPath"] = "/services/getlanguages"
configurations["responseText"] = "{\"label\":\"Java\"},{\"label\":\"Perl\"}"
configurations["contentType"] = "application/json"
configurations["eval"] = "function (req,responseText) { return '[' + responseText + ']'; }"
configurations["statusCode"] = "200"
configurations["delayTime"] = "0"
# Actually make the call to register this information.
mslclient.setMockRespond("localhost", "8001", configurations)
# Trigger event that fires off request.
autocomplete.send_keys('J')
time.sleep(1)
# Grab the dropdown elements and validate the data against the registered response to
# make sure the initial register worked.
elementOne = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[1]')
elementTwo = chrome.find_element_by_xpath('.//ul[contains(@class, "ui-autocomplete")]/li[2]')
assert elementOne.get_attribute("textContent") == 'Java'
assert elementTwo.get_attribute("textContent") == 'Perl'
# Unregister the request path
mslclient.unRegisterMock("localhost", "8001", '/services/getlanguages')
autocomplete.clear()
chrome.find_element_by_id('postRequest').click()
autocomplete.send_keys('J')
assert elementOne.is_displayed() == False
@classmethod
def tearDownClass(self):
'''Closes the browser since it is no longer needed.'''
chrome.close()
chrome.quit()
if __name__ == '__main__':
unittest.main()
gem install msl-client
require 'msl-client'
An example test has been provided along with the other files as a guide on how it can be used and to see how it performs. This test also uses the sample application located on the
GitHub page and works by registering responses using text and a template, validates intercepted requests, and unregisters a mock
when it is no longer needed.
require 'msl-client'
require 'test/unit'
require 'json'
require 'selenium-webdriver'
class MockapiTest < Test::Unit::TestCase
class << self
# Sets up the webdriver before before starting the tests.
def startup
ENV['HTTP_PROXY'] = ENV['http_proxy'] = nil
$driver = Selenium::WebDriver.for :chrome
$driver.navigate.to 'http://localhost:8001/msl-sample-app/index.html'
end
# Kills the webdriver instance when all tests are finished.
def shutdown
$driver.quit
end
end
# This is used to test the basic text response. A function is executed
# on the web-server to format the text.
def testTextResponse
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = $driver.find_element(:id => 'autocomplete')
autocomplete.clear()
# Take focus off of the autocomplete box to make sure the dropdown
# goes away.
$driver.find_element(:id => 'postRequest').click()
sleep(1)
# Setup all of the needed data like request path, the response, function
# for formatting, etc.
configurations = {}
configurations['requestPath'] = '/services/getlanguages'
configurations['responseText'] = '{"label":"Java"},{"label":"Perl"}'
configurations['contentType'] = 'application/json'
configurations['eval'] = 'function (req,responseText) { return "[" + responseText + "]"; }'
configurations['statusCode'] = '200'
configurations['delayTime'] = '0'
# Actually make the call to register this information.
setMockRespond('localhost', 8001,configurations.to_json)
# Trigger event that fires off request.
autocomplete.send_keys 'J'
# Grab the dropdown elements and validate the data against the registered response.
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {$driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]').displayed?}
optionOne = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]')
optionTwo = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[2]')
assert_equal('Java',optionOne.text)
assert_equal('Perl',optionTwo.text)
end
# This tests using a template to generate a response.
def testTemplateResponse
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = $driver.find_element(:id => 'autocomplete')
autocomplete.clear()
# Take focus off of the autocomplete box to make sure the dropdown
# goes away.
$driver.find_element(:id => 'postRequest').click()
sleep(1)
# Register the template that will be used later with the key-value pairs.
registerTemplate('localhost', 8001,
'[{"label":"{{param1}}"},{"label":"{{param2}}"}]', 'example')
# Setup all of the needed data like request path, key-value pairs, and template id.
configurations = {}
configurations['requestPath'] = '/services/getlanguages'
configurations['contentType'] = 'application/json'
configurations['statusCode'] = '200'
configurations['delayTime'] = '0'
# The values that are to replace the keys in the registered template.
keyVals = {}
keyVals['param1'] = 'German'
keyVals['param2'] = 'English'
configurations['keyValues'] = keyVals
configurations['id'] = 'example'
# Actually make the call to register this information.
setMockRespond('localhost', 8001,configurations.to_json)
# Trigger event that fires off request.
autocomplete.send_keys 'J'
# Grab the dropdown elements and validate the data against the registered response.
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until {$driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]').displayed?}
optionOne = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]')
optionTwo = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[2]')
assert_equal('German',optionOne.text)
assert_equal('English',optionTwo.text)
end
# This tests the ability to intercept, and validate intercepted, get requests.
def test_getIntercepted
# Register the request path of the get request to be intercepted
setInterceptXHR('localhost', 8001, '/services/getservice')
# Put text into input box which will be added to get request
inputBox = $driver.find_element(:id => 'getInput')
inputBox.send_keys 'GET Example'
# Trigger the get request
postButton = $driver.find_element(:id =>'getRequest')
postButton.click()
sleep(1)
# Retrieve all request intercepted that have the provided request path
intercepted = JSON.parse(getInterceptedXHR('localhost', '8001', '/services/getservice'))
# Validate the method and url of the intercepted request
req1 = intercepted['xhr_1']
assert_equal('GET',req1['xhr']['method'])
assert_equal('/services/getservice?term=GET+Example', req1['xhr']['url'])
assert_equal(nil, req1['post'])
end
# This tests the ability to intercept, and validate intercepted, post requests.
def test_postIntercepted
# Register the request path of the post request to be intercepted
setInterceptXHR('localhost', 8001, '/services/postservice')
# Put text into input box which will be added to post request
inputBox = $driver.find_element(:id => 'output-box')
inputBox.send_keys 'POST Example'
# Trigger the post request
postButton = $driver.find_element(:id =>'postRequest')
postButton.click()
sleep(1)
# Retrieve all request intercepted that have the provided request path
intercepted = JSON.parse(getInterceptedXHR('localhost', '8001', '/services/postservice'))
# Validate the method and url of the intercepted request
req1 = intercepted['xhr_1']
assert_equal('POST',req1['xhr']['method'])
assert_equal('/services/postservice', req1['xhr']['url'])
assert_equal(req1['post'], req1['post'][/timestamp=\d*&text=POST\+Example/])
end
# This is used to test unregistering a request path.
def testUnRegisterMock
# Clear the autocomplete to make sure this test starts from scratch.
autocomplete = $driver.find_element(:id => 'autocomplete')
autocomplete.clear()
# Take focus off of the autocomplete box to make sure the dropdown
# goes away.
$driver.find_element(:id => 'postRequest').click()
sleep(1)
# Setup all of the needed data like request path, the response, function
# for formatting, etc.
configurations = {}
configurations['requestPath'] = '/services/getlanguages'
configurations['responseText'] = '[{"label":"Java"},{"label":"Perl"}]'
configurations['contentType'] = 'application/json'
configurations['statusCode'] = '200'
configurations['delayTime'] = '0'
# Actually make the call to register this information.
setMockRespond('localhost', 8001,configurations.to_json)
# Trigger event that fires off request.
element = $driver.find_element(:id => 'autocomplete')
element.send_keys 'J'
# Grab the dropdown elements and validate the data against the registered response to make sure
# it worked before unregistering.
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {$driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]').displayed?}
optionOne = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]')
optionTwo = $driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[2]')
assert_equal('Java',optionOne.text)
assert_equal('Perl',optionTwo.text)
# Unregister the request path
unRegisterMock('localhost', 8001, '/services/getlanguages');
autocomplete.clear()
$driver.find_element(:id => 'postRequest').click()
element.send_keys 'J'
assert_true(!$driver.find_element(:xpath => './/ul[contains(@class, "ui-autocomplete")]/li[1]').displayed?)
end
end
If you are using the browser client to write your tests, we recommend you to use the Karma Plugin to run your tests. The karma plugin will allow automatic starting of MSL Server and execution of tests using the MSL Browser Client.
{
"devDependencies": {
"karma": "~0.12.0",
"karma-msl": "~0.0.14"
}
}
npm install karma-msl --save-dev
// karma.conf.js
module.exports = function(config) {
config.set({
frameworks: ['jasmine', 'msl'],
files: [
'spec/*.js'
],
// configuration for msl plugin
msl: {
port: '8002', //port to start msl server. 8000 by default.
basedir: '../src/', // directory containing the app code (front-end code under test). current dir by default.
debug: 'true', // true to turn on debugging. false by default.
extensions: 'parseUrl.js' // specify extension files you want to plugin to MSL to parse URL differently.
},
// this port should match the msl port specified in msl plugin config
proxies: {
'/' : 'http://localhost:8002/'
},
// this port should match the msl port used within the tests
port: 8001,
});
};
karma start karma.conf.js