Nightwatch Page Object persistence - nightwatch.js

Using Nightwatch's Page Object capability, I have all the elements of a page defined as well as its URL. After navigating to the page (e.g., page.navigate()), the code waits for the one of the elements to be visible and then records the values of several elements before clicking on another element that leaves the page. I want to ensure that the page is no longer displayed by waiting for that same element to not be displayed, but that second wait always times out and I'm forced to look for an element that's not on that page to verify I've left the page. For example,
module.exports.command = function (settings)
{ var page = this.page.settings()
page.navigate()
.waitForElementVisible('#firstName',3000)
.getValue('#firstName', function(r) {settings.firstName = r.value})
.getValue('#lastName', function(r) {settings.lastName = r.value})
.waitForElementVisible('#firstName',3000)
.click('#dashboard')
.waitForElementNotVisible('#firstName',3000) // this times out
this.verify.visible('#AvailableProcedures') // but this works
}
My question is: does a page object become invalid once the page is no longer displayed?

'Leaves the page',does that mean navigate to another url ? If yes,you should check the element is 'present or not', instead of 'visible or not'
module.exports.command = function (settings)
{ var page = this.page.settings()
page.navigate()
.waitForElementVisible('#firstName',3000)
.getValue('#firstName', function(r) {settings.firstName = r.value})
.getValue('#lastName', function(r) {settings.lastName = r.value})
.waitForElementVisible('#firstName',3000)
.click('#dashboard')
.waitForElementNotPresent('#firstName',3000,false,
function(),'Element is not there');
}
E.g , when i try to login:
loginPage = client.page.login();
loginPage
.navigate()
.waitForElementVisible('#username',5000,false)
.setValue('#username',username)
.setValue('#password',password)
.click('#submit')
.waitForElementNotPresent('#username,5000,false)

Related

GravityView Ajax Link

I have a table created with GravityView and I want to implement the single entry link with Ajax so that the page does not refresh and the URL does not change.
Is such a thing possible?
enter image description here
You can load the single entry page with jQuery .load method.
You would need to pass the URL of the page, in this case I am trying to get the content on another page whose URL is in the anchor link of the table, in your case its link field.
So i give the .load method URL + the id of the accordion in which the content i need to display exists, and a call back function.
Here how I did it.
jQuery( document ).ready(function($) {
// select the div where you want to display content
var $loadedContent = $('#fl-accordion-5c450fd66133e-panel-0');
// register an event, get the click event of the link
$(document).on('click','.gv-field-3-date_created a', function(event) {
//stop the link form opening
event.preventDefault();
//get URL from the href attribute of the anchor link
var $url = $(this).attr("href");
// send the request and get the response, In my case I am trying to show the content inside a accordian, so i have taken its ID and added that with URL
$loadedContent.load($url+' #fl-accordion-5c450fd66133e-panel-0', completeFunction);
return false;
});
function completeFunction(responseText, textStatus, request) {
if(textStatus == 'error') {
// show a relevant message
$loadedContent.text('An error occurred during your request: ' + request.status + ' ' + request.statusText);
}
}
});
Just add your classes, and it will get the Job Done.
Thanks for using GravityView! Zack here, founder.
We’re going to be adding this functionality later this year. If you wait a few months, it’ll be ready!

Pass sidedrawer data to homepage

I have used the SideDrawer example and have a series of dropdown's on my SideDrawer. After the last selection I need to display details on the underlying page, in this case the homepage. How do I update the underlying page as a result of my selections.
Don't know where to start.
exports.installationIndexChanged = function (args){
const drawerComponent = args.object;
const sideDrawer = app.getRootView();
var context = sideDrawer.bindingContext;
var installation = drawerComponent.items[args.newIndex];
console.log(installation);
var installDD = drawerComponent.getViewById("installation");
var selectedInstall = installDD.selectedIndex;
appSettings.setNumber("id",(installDD.get("items").getValue(selectedInstall)));
}
the last line in the code above gets the ID of the record I need to display. I'm not sure if I can address the underlying page at this point, or need to know when the sidedrawer closes, display the record then. My preference would be to keep the sidedrawer open and display the record on the homepage first. The user can then close the sidedrawer to view the complete record.

Nativescript Get Current Page

How can I get the current screen I'm working on? For example, I have a slidedrawer containing buttons to navigate to another page. When I'm on a certain page(About Page) and when I tap the button to navigate to the About Page, I want to just close the slidedrawer if it is on the same page.
My idea is that to get the current page and just compare it but I dont know how.
Note: The slidedrawer content menu is a custom component.
There are several ways to solve this problem. The easiest is to install the nativescript-dom plugin and then you can do this really simply:
// This will return an array of elements that are SlideDrawer's.
var slideDrawers = getElementsByTagName('SlideDrawer');
or even better is if you have assigned your SlideDrawer an id, you can do
<!-- Declarative XML -->
<SlideDrawer id="myId">...</SlideDrawer>
// JS: Will return a single element that matching the id.
var mySlideDrawer = getElementById('myId');
However, if you just want to not use any helpers and you want to get direct access to the currentPage the method is to do:
var frame = require('ui/frame');
var myPage = frame.topmost().currentPage;
Please note; the currentPage will reflect the old page while navigation is taking effect until the navigatedTo event is fired, at that point the currentPage is actually updated to be the currentPage. However, if you are looking for the current page during any of the navigation events (NavigatingTo, NavigatedTo, Loaded, Unloaded) each of those events are transferred a parameter with the current page as part of the object.
exports.onNavigatedTo = function(args) {
var page = args.object;
// do what you want with the current page variable
}

jQuery Mobile cache pages in order

I have a list of a tags that are hidden. I tried using the data-prefetch attribute as described in the jquery mobile docs. The only problem is it fires off an ajax request for all of them at once and there is no garentee of the order that they get loaded in.
The ordering is very important in what pages are shown next via swipe.
So I decided to try and cache the links programatically via this bit of code.
var last_cache_page = false;
function cache_next_page(){
if(last_cache_page == false){
var cache_link = $('.cache').first();
last_cache_page = cache_link;
}
else{
var cache_link = last_cache_page.nextAll('.cache');
last_cache_page = cache_link;
}
//Start Caching any other pages that we want to swip to
$.mobile.loadPage(cache_link.attr('href'), {showLoadMsg: false});
}
So on $(document).on('pageshow') I call cache_next_page(). That part works fine the real problem is that when using $.mobile.loadPage no jquery mobile page related events fire once the first cached page is interested into the dom.
I have tried pageshow, pageinit and pageload but they only fire the first time the page is loaded. Now if I load the first page which starts the caching directly. That is to say with out visiting any other pages in the application it DOES trigger all the expected events such as pageload.
It is only when you start on page_1 and then go to page_2 (which has the code to start the cache) that it fails to have a pageload event triggered when the cached page is inserted into the dom.
I found out there there is a .done on the object that is returned from .loadPage so I have modified my code as follows to allow it to cache my links in order.
var last_cache_page = false;
function start_caching(){
if(last_cache_page == false){
var cache_link = $('.cache').first();
last_cache_page = cache_link;
}
else{
var cache_link = last_cache_page.nextAll('.cache').first();
last_cache_page = cache_link;
}
if(cache_link.length == 1){
//Start Caching any other pages that we want to swipe to
new_page = $.mobile.loadPage(cache_link.attr('href'), {showLoadMsg: false});
new_page.done(function(){
start_caching();
});
}
}

Livequery fires click no matter where the user clicks in the document

I have replaced the traditional select/option form elements with a nifty little popup window when a triggering image is clicked. The page is for accounting purposes and so multiple line items are to be expected. I've written the javascript that will dynamically generate new line item select/option elements. When the page loads, the initial set of choices loads and the user can click on them, get a pop up with some choices, choose one and then the box closes. The move to the next choice and so on and so forth. I've added livequery to my code for those dynamic elements. However... the livequery("click"...) seems to fire no matter where the user clicks on the page. Very frustrating.
I've read on here how great "live()" is in jQuery 1.3, but I am not able to upgrade fully to jquery 1.3 because a custom JS file depends on 1.2, so using live() is out of the question, however I have invoked the livequery() plugin and I really need to understand if I'm using it correctly.
I will post partial code. There's just way too much to post all of it.
Basically, I'm searching for divs starting with "bubble" and then a number afterwards. Then run the event on each them. Only bubble1 is static, 2 and up are dynamic. Am I missing the whole usage of livequery?
>$jb('div[id^="bubble"]').each(function () {
> var divid = $jb('div[id^="bubble"]').filter(":first").attr("id");
>var pref = "bubble";
>var i = divid.substring((pref.length));
>var trigger = $jb('#trigger' + i, this);
>var popup = $jb('#pop'+ i, this).css('opacity', 0);
>var selectedoption = $jb('selectedOption' + i, this);
>var selectedtext = $jb('selectedOptionText' + i, this);
>$jb([trigger.get(0), popup.get(0)]).livequery("click",
> function () {
>//alert(i);
// code removed for brevity (just the contents of the popups)
>});
Live works by using event delegation. A click event is attached to the body, and anytime something is clicked the selector is tested against the target. If it passes the selector test it calls the function (thus simulating a click event).
You probably want something like this:
$('div[id^="bubble"]').livequery("click", function() {
var divId = $(this).attr("id");
var i = divId.substring("bubble".length);
var trigger = $("#trigger" + i, this);
var popup = $("#pop" + i, this).css("opacity", 0);
// alert(i);
}

Resources