page object: visit <page_url> in nightwatch.js - javascript

In Geb and WATIR there are certain keywords which we use to visit to the page_url which we have specified in page class. E.g. to keyword in Geb and visit keyword in WATIR.
What similar we can use in nightwatch.js. This is what I have tried but it gives error:
I have tried:
module.exports = {
url: function () {
return this.api.globals.launchUrl + "/goto/desiredPage.html";
},
commands: [pageCommands],
elements: {}
};
In page class I am using it as:
desiredPage
.url()
.foo()
.bar();
client.end();
but it is giving error .url is not a function.

You can see the nightwatch examples inside the nightwatch folder for example:
[page-objects/home.js]
var searchCommands = {
submit: function() {
this.waitForElementVisible('#submitButton', 3000)
.click('#submitButton')
.api.pause(1000);
return this; // Return page object for chaining
}
};
module.exports = {
url: 'http://google.com',
commands: [searchCommands],
elements: {
searchBar: { selector: 'input[name=q]' },
submitButton: { selector: 'button[type=submit]' }
}
};
and then in the test:
/* jshint expr: true */
module.exports = {
'Demo Google search test using page objects' : function (client) {
var homePage = client.page.home();
homePage.navigate();
homePage.expect.element('#searchBar').to.be.enabled;
homePage
.setValue('#searchBar', 'Nightwatch.js')
.submit();
var resultsPage = client.page.searchResults();
resultsPage.expect.element('#results').to.be.present.after(2000);
resultsPage.expect.element('#results').to.contain.text('Nightwatch.js');
resultsPage.expect.section('#menu').to.be.visible;
var menuSection = resultsPage.section.menu;
menuSection.expect.element('#web').to.be.visible;
menuSection.expect.element('#video').to.be.visible;
menuSection.expect.element('#images').to.be.visible;
menuSection.expect.element('#shopping').to.be.visible;
menuSection.productIsSelected('#web', function(result) {
this.assert.ok(result, 'Web results are shown by default on search results page');
});
client.end();
}
};
so "url()" command in pages does not exist you need to define the url in te page and the use "navigate()" instead.

Related

Using a Javascript Data

I am using Framework7.
In app.js I have these codes to specify routes.
var app = new Framework7({
root: '#app',
theme: 'ios',
tapHold: true,
view: {
stackPages: true,
},
// Create routes for all pages
routes: [
{
path: '/',
url: 'index.html',
},
{
path: '/single/',
url: 'pages/post.php?id=',
}
]
});
And I have this data
var getId = "";
$(".yaziaclass").click(function() {
var getId = this.id;
});
I want to use this data in route configuration.
url: 'pages/post.php?id='+getId
The problem is it doesn't see the id. I guess it's because of the click action.
I want to change the getId's value when an user click a post. And use it in route configuration codes.
How can I fix it?
Modifying the function written above to ES6.
let getId = "";
$(".yaziaclass").click(() => {
getId = this.id;
});
console.log(getId);
If you don't want to use ES6, then use the following:
var getId = "";
function handleClick(){
getId = this.id
}
$(".yaziaclass").click(handleClick.bind(this));
console.log(getId); // should have updated the global `getId` value
I would also suggest you to read about Global and Local scopes in Javascript.

Night watch pageobject element selectors are not working with # notation

Selectors when passed using # notation from the test function to the page object are not working.
Here's my homepage object.
module.exports = {
url: function () {
return this.api.launchUrl;
},
elements: {
dropdownSelector: {
selector: '#input-13',
locateStrategy: 'css selector'
},
dropdownAuthSelector: {
selector: '#list-item-18-5 > span > span.ml-1',
locateStrategy: 'css selector'
},
},
commands: [{
setDropdown(selector, value) {
let { selectDropdown } = require('../modules/Utils.js');
selectDropdown(this.api, selector, value);
return this;
}
}]
};
Utils.js
module.exports.selectDropdown = function (self,selector,value) {
return self.click(selector).click(value);
}
Test js file.
module.exports = {
'#tags': ['home'],
'Dashboard Dropdown test'(browser) {
const homePage = browser.page.homepage();
homePage
.navigate()
//.setDropdown(homePage.elements.dropdownSelector.selector, homePage.elements.dropdownAuthSelector.selector)
.setDropdown('#dropdownSelector', '#dropdownAuthSelector')
.assert.urlContains('Authentication').end();
}
};
So basically
setDropdown(homePage.elements.dropdownSelector.selector, homePage.elements.dropdownAuthSelector.selector) Works fine, but when I use # notation it doesn't work
.setDropdown('#dropdownSelector', '#dropdownAuthSelector') and throws below error
Error
Error while running .locateMultipleElements() protocol action: invalid selector: An invalid or illegal selector was specified
Error while running .locateMultipleElements() protocol action: invalid selector: An invalid or illegal selector was specified
I don't think they can be access directly thru # due to the queueing behavior of nightwatch. Page object commands are not autoadded to the main queue. Also, why not define custom command HomePage page object, where you can access them directly and then just invoke that command in test?

Nightwatch cannot take screenshot return is not a function

I'm using nightwatch-cucumber module, which works pretty great,
but I can't save any screenshot in my testing step.
nightwatch.config.js
...
test_settings: {
default: {
screenshots : {
enabled : true,
on_failure : true,
path: 'screenshots/'
},
...
step.js
...
return pageObj
.submit()
.waitForElementVisible('#status')
.getText('#status')
.saveScreenshot('./screenshots')
.expect.element('#status').text.to.contain(status);
...
console error
TypeError: pageObj.submit(...).waitForElementVisible(...).getText(...).saveScreenshot is not a function
any suggestion?
Use this one in the command section. In page object file.
const commands = {
saveScreenshot(filePath) {
this.api.saveScreenshot(filePath);
return this;
}
module.exports = {
url: 'url',
commands: [commands],
elements: {
.......
}
};
}

How to do Framework7 routing with jQuery?

I am developing a hybrid mobile app with Framework7. I finished the user interface successfully and now I want to add functionality to my app. My problem is the navigation from one .html to another.
At the user interface i did the navigation with links, like this:
LOGIN
Because of some checks I removed the whole href-tag and here I come to the problem, how can i do this linking in jQuery?
I tried a lot, also followed the public "Router JavaScript API" (https://v1.framework7.io/docs/router-api.html) but nothing worked well (NOTE: this is not my whole code, just the affected parts):
Attempt 1
var myApp = new Framework7 ({});
var mainView = myApp.views.add('.view-main');
var app = {
init: function () {
events.doClickFunctions();
},
login: {
success: function () {
//here should be the linking done
mainView.router.load('/homepage/');
}
}
};
Problem: "myApp.views.add is not a function"
Attempt 2
var myApp = new Framework7 ({});
var mainView = myApp.addView('.view-main');
var app = {
init: function () {
events.doClickFunctions();
},
login: {
success: function () {
//here should be the linking done
mainView.router.load('/homepage/');
}
}
};
Problem: "myApp.addView is not a function"
And i tried some other combinations, but nothing worked.
Furthermore, I made a workaround: If the checks are successful, the href attribute will be added with jQuery and a virtual click is made on the element. So the user experience is like i want it to, but I guess thats not how it is supposed to work?
Thank you in advance!
try this
var app = new Framework7({
id: 'io.framework7.testapp',
precompileTemplates: true, //
template7Pages: true,
root: '#app',
theme: theme,
cache: false ,/* disable caching */
data: function () {
},
methods: {
helloWorld: function () {
app.dialog.alert('Hello World!');
},
},
routes: routes,
vi: {
placementId: 'pltd4o7ibb9rc653x14',
}
});
app.views.main.router.navigate('/login/');
for routing to another Page in jq use this :
app.views.main.router.navigate('/login/');

How load functions with same name

I'm developing by Openui5 a portal. My portal have 2 apps. I I have organized the code in folders:
root
|
|____app1
|____app2
In app1 folder I have util1.js with a function getInfo() and in app2 folter I have util2.js with function getInfo() (same name).
Now my portal, at root login, load all js files in all subfolders, and only the last loaded getInfo() function work (correct???)
I think in the future to dynamically load the js file of appX only when the user enter in the appX.
In this way it work correctly??
Don't make your getInfo functions global. (This would be good advice even if you only had one of them, the global namespace is very crowded.)
Instead, ideally, have a single global for your portal's apps, perhaps called Apps, which is an object. Then have each app add itself to that object as a property, using the app's name. So:
portal.js:
var Apps = {};
app1.js:
Apps.App1 = {
getInfo: function() {
// ...
},
somethingElse: function() {
// ...
}
// ...and so on...
};
app2.js:
Apps.App2 = {
getInfo: function() {
// ...
},
somethingElse: function() {
// ...
}
// ...and so on...
};
Or you might go further and have an app registration function:
portal.js:
var MyPortal = {
apps: {},
register: function(name, app) {
if (this.apps.hasOwnProperty(name)) {
throw new Error("There is already an app called '" + name + "' registered.");
}
this.apps[name] = app;
}
};
app1.js:
MyPortal.register("App1", {
getInfo: function() {
// ...
},
somethingElse: function() {
// ...
}
// ...and so on...
});
app2.js:
MyPortal.registerApp("App2", {
getInfo: function() {
// ...
},
somethingElse: function() {
// ...
}
// ...and so on...
});

Categories