Skip to content

Instantly share code, notes, and snippets.

@codeluggage
Last active October 22, 2021 04:47
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeluggage/318546fb0cee5613346ecf7443220198 to your computer and use it in GitHub Desktop.
Save codeluggage/318546fb0cee5613346ecf7443220198 to your computer and use it in GitHub Desktop.
Convert ES6 classes to basic Javascript objects to export for Nightwatch
'use strict';
/*
* The purpose of this function is to convert an ES6 class to either:
* 1) A test suite if it has "tests" as a property
* 2) A page object with optional "elements", "commands" and "url"
* @param es6Class The actual class object (not instance of the class) to convert
*/
module.exports = function(es6Class) {
let properties = Object.getOwnPropertyNames(es6Class.prototype);
// First, determine if this is a test suite with a tests() function
if (properties.indexOf("tests") != -1) {
// The tests() function has the structure we need already,
// so we can pipe it directly into the export for Nightwatch
return es6Class.prototype.tests();
}
let converted = {};
let commands = {};
properties.forEach((name) => {
// Constructors are functions, but we don't care about them so just continue the forEach loop
if (name === "constructor") {
return;
}
// elements() gives us the element identifiers in an object structure, so we just set it
if (name === "elements") {
converted.elements = es6Class.prototype.elements();
return;
}
// url() is used for the navigate() calls without arguments, but it is not a command,
// so we assign it directly to to the final class
if (name === "url") {
converted.url = function() {
// In case the callee has arguments, pass them on
return es6Class.prototype.url.apply(this, Array.from(arguments));
}
return;
}
// All other cases accounted for, the function is a command for sure at this point
commands[name] = function() {
// Do the call first, including potential arguments from the callee, before comparing with 'this'.
// If we did not do the comparison against 'this', we could not effectively chain function calls.
return es6Class.prototype[name].apply(this, Array.from(arguments));
}
});
converted.commands = [commands];
return converted;
};
/* Very simple page object example:
'use strict';
class MyPageObject {
url() {
return `${this.api.launch_url}/my-test-url`;
}
performSignup() {
return this
.waitForElementVisible('@signupButton')
.click('@signupButton')
.waitForElementNotPresent('@signupButton')
.waitForElementVisible('@profileImage');
}
elements() {
return {
signupButton: '.signup-button',
signOutButton: '.signup-button',
profileImage: '.profile-image',
}
}
}
module.exports = require('../es6ToNightwatch')(MyPageObject);
*/
/* Very simple test suite example:
'use strict';
class SignupTests {
tests() {
return {
'sign up as a new user': this.signupNewUser,
'sign out': this.signOut,
}
}
signupNewUser(browser) {
const signupPage = browser.page.signupPage();
browser.deleteCookies(() => {
signupPage
.performSignup()
});
}
signOut(browser) {
const signupPage = browser.page.signupPage();
signupPage
.click("@signOutButton")
.waitForElementNotPresent("@signOutButton")
.waitForElementVisible("@signupButton");
}
}
module.exports = require('../es6ToNightwatch')(SignupTests);
*/
@codeluggage
Copy link
Author

Does not handle sections yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment