Testcafe - unable to dismiss browser dialog - dialog

I have a function in my test that clicks a button (removePhoneNumberButton). When this button is clicked, a browser alert shows up.
All I'd like to do is to be able to dismiss it in order to proceed with the test, but I'm not sure how to achieve this.
I have consulted the Testcafe documentation on handling native dialogs, but to no avail.
The following:
.setNativeDialogHandler(() => true) }
didn't seem to work either.
Here is my code:
this.addAndRemovePhoneNumber = async function (t, phoneNumber) {
await t
.expect(profilePageElements.uneditablePhoneNumberInput.innerText)
.contains(phoneNumberAfterServerSideFormatting)
.click(profilePageElements.removePhoneNumberButton)
.setNativeDialogHandler(() => true) }
Thanks.

Call the setNativeDialogHandler function before you perform a click:
await t
.expect(profilePageElements.uneditablePhoneNumberInput.innerText)
.contains(phoneNumberAfterServerSideFormatting)
.setNativeDialogHandler(() => true)
.click(profilePageElements.removePhoneNumberButton)

Related

Can you invoke a method in Cypress using dynamically instantiated objects?

I'm trying to write e2e tests with Cypress and would like to dynamically be able to intantiate objects and use them as parameters for the invoke method.
The subject under test is a SPA with a redux store. For debugging (and possibly e2e testing), I have a window.debug object. The debug object exposes a dispatchAction(action: Action) method and properties that return classes, for instance Actions.SetMenu.
So on the browsers console I can call something like this to dispatch an action:debug.dispatchAction(new debug.Actions.SetMenu({ menu }))
For Cypress I need something like the following:
let setMenuAction;
cy.window()
.its('debug')
.then(debug => {
const SetMenu = debug.Actions.SetMenu;
setMenuAction = new SetMenu({ menu });
console.log(setMenuAction);
return debug;
})
.invoke('dispatchAction', setMenuAction);
But the above doesn't work. Is there a way to achieve what I'm trying?
Edit: Got it to work, was an async problem:
cy.window()
.its('debug.Actions.SetMenu')
.then(SetMenu => {
cy.window()
.its('debug')
.invoke('dispatchAction', new SetMenu({ menu }));
})
cy.window()
.its('debug.Actions.SetMenu')
.then(SetMenu => {
cy.window()
.its('debug')
.invoke('dispatchAction', new SetMenu({ menu }));
})

ChatBot back to previous dialog

I've created a chatbot using Node.js and the flow of dialogs works fine til the endDialog. Im having issues implementing a back option so it can jump back only to previous dialog. Can anyone please guide me how to solve that?
.reloadAction(
"restartBenefits", "Ok. Let's start over.",
{
matches: /^start over$|^restart$/i
}
)
.cancelAction(
"cancelRequest", "Thank you for reaching out, Good bye!",
{
matches: /^nevermind$|^cancel$|^cancel.*request/i,
confirmPrompt: "This will cancel your request. Are you sure?"
}
);
Use a customAction
In this case you can listen for whatever you want to be a keyword for "back" and then simply route the user back to that dialog using replaceDialog
bot.customAction({
matches: /back|last/gi, //whatever prompts you want to match.
onSelectAction: (session, args, next) => {
session.replaceDialog(PreviousDialog); //variable with the last dialog in it, set that somewhere, such as the end of your previous dialog
}
})
I think that at the final step of the dialog waterfall you need to add the last lines in this sample step:
/**
* This is the final step in the main waterfall dialog.
* It wraps up the sample "book a flight" interaction with a simple confirmation.
*/
async finalStep(stepContext) {
// If the child dialog ("bookingDialog") was cancelled or the user failed to confirm, the Result here will be null.
if (stepContext.result) {
const result = stepContext.result;
// Now we have all the booking details.
// This is where calls to the booking AOU service or database would go.
// If the call to the booking service was successful tell the user.
const timeProperty = new TimexProperty(result.travelDate);
const travelDateMsg = timeProperty.toNaturalLanguage(new Date(Date.now()));
await stepContext.context.sendActivity(ActivityFactory.fromObject(this.lgTemplates.evaluate('BookingConfirmation', {
Destination: result.destination,
Origin: result.origin,
DateMessage: travelDateMsg
})));
}
// =====> HERE: Restart the main dialog with a different message the second time around
return await stepContext.replaceDialog(this.initialDialogId, { restartMsg: 'What else can I do for you?' });
}
Just change the this.initialDialogId accordingly.

Aurelia popup when refreshing the page not working

As we know, we can put a pop up asking if we are sure about refreshing the page when we click the refresh button on the browser. Usually it is done by adding an event listener on onbeforeunload.
However, in my Aurelia application, I try to do that but it's not working.
let's say this is my app.js ( root ModelView )
export class App {
this.refreshClicked = () =>{ return "Are you sure you want to exit?"; };
attached(){
window.addEventListener("onbeforeunload", this.refreshClicked);
}
But it is not working, however, if we replace the return statement to console.log("clicked") I can see that the listener works without any problem.
Any help?
First of all, if you are adding event handler through window.addEventListener, you don't use on prefix in that case. So it's either:
attached() {
window.addEventListener('beforeunload', this.refreshClicked);
}
or an older, not recommended, syntax:
attached() {
window.onbeforeunload(this.refreshClicked);
}
Second, you'll need to set the returnValue property on Event object and also return the same string value to support more browsers. To learn more about this event (and various browser quirks), check out its MDN page.
Your refreshClicked should look like this:
this.refreshClicked = e => {
const confirmation = 'Are you sure you want to exit?';
e.returnValue = confirmation;
return confirmation;
};

galen: how to wait dynamic new page with same url

I started working with Galen and I had this test that was working perfectly:
this.HomePage = $page('Welcome Page', {
aboutButton: 'nav.navbar .about'
});
this.AboutPage = $page('About page', {
modalContent: 'div.modal-content',
supportLink: '.support-link',
dismissButton: '.dismiss'
});
var homePage = new HomePage(driver);
homePage.waitForIt();
homePage.aboutButton.click();
var aboutPage = new AboutPage(driver);
aboutPage.waitForIt();
I understand that the waitForIt method waits for all the attributes defined by page so the framework knows when to execute the next statement.
Now, I want to run this as a grunt task and I've been using grunt-galenframework, and I configured it correctly, everything is working, but I can't make the previous test pass, the task code is as follows:
load('../gl.js');
forAll(config.getDevices(), function (device) {
test('simple test on ' + device.deviceName, function () {
gl.openPage(device, config.getProjectPage(), "Welcome Page", {
aboutButton: 'nav.navbar .about'
});
elements.aboutButton.click();
// MISSING WAIT FOR ABOUT_PAGE
gl.runSpecFile(device, './test/responsive/galen/about.gspec');
});
});
As you can see, I get into the Welcome Page and then I need to click a button, wait for a dialog to appear, and then check the about.gspec specs (they verify elements inside the dialog).
So how can I add a wait for new elements to appear on the same URL? it feels like grunt-galenframework only offers wait when entering a new url, with the openPage method.
you could try
elements.newElement.waitToBeShown()
The methods from here should be available.
PS: I'm the author of the grunt plugin for Galen and also involved in the development of the Galen Framework itself

How to identify a tab is reloading, I mean actual page reload

How to identify a tab is reloading, I mean actual page reload?
I see chrome.tabs.onUpdated event, but for this event status is 'loading' even in case of AJAX calls from a webpage.
How can I detect a page is getting reloaded ?
You are right, looks like not possible to recognize AJAX and page reload calls. As workaround you could listen for onunload event for tab webpage. You probably need to check if tabid and url were not changed after that.
But do you really need to know if page reloaded?
It's an old question, but here is my solution that could be in help (without AIAX).
Since the method 'chrome.tabs.get()' return a promise, you can use the 'callback function' to check the current 'tab.status'.
Setting a boolean variable 'waitingForComplete = true', you will run your code, only when the tab will return at status = 'complete'.
background.js
var waitingForComplete = false;
chrome.tabs.onUpdated.addListener((tabId. changeInfo,tab) => {
if(changeInfo.status == 'complete'){
if(waitingForComplete){
waitingForComplete = false;
// runYourCode...
}
}
};
function checkTabStatusComplete(tabId){
chrome.tabs.get(tabId. function(tab){
if(tab.status == 'complete'){
// runYourCode...
} else {
waitingForComplete = true;
}
}
};

Resources