I am working in cypress.
Steps to repro
I just visit the login page by cy.visit()-spinner is loading
passed the credentials using type-spinner is still loading
click on submit.-spinner is still loading
its throwing error .. why because the login page XHR calls didnt get completed thats why still we can see spinner loading in top and i tried to click the submit button before it gets loaded,may be because of poor network-telling invalid credentials.
I believe you have to wait for the XHR request to get completed and validate the page load or perform other actions.
Here is a sample,
// Wait for the route aliased as 'getAccount' to respond
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('#getAccount').then((xhr) => {
cy.get('#loading-bar').should('not.be.visible')
})
Here is a similar solution which I have previously given - Cypress:Is there any way to check invisibility of an element
You check if the button is present and then click on the button.If
describe('check if button present', function () {
it('check for button using CSS Selector', function () {
cy.visit(url)
let found = false
let count=0
while (!found) {
const nonExistent = Cypress.$('.btn-selector')
if (!nonExistent.length) {
found = false
count=count+1
cy.wait(1000)
if(count==60)
{
found = true
cy.log('Element not found after 60 seconds..Exit from loop!!!')
}
}
else
{
found = true
cy.get('.btn-selector').click()
}
}
})
})
Related
As we know, in mobile web-browser, if you click back button, the web-app will go to previous page, right?
But what if I want to make a certain condition which will prevent the web-app to go to previous page.
For example, if a SweetAlert2 dialog is popped-up, the back button will close the SweetAlert2 dialog.. but if there is no SweetAlert2 dialog, the back button will go to previous page..
The code I expected is like below:
export default {
mounted() {
document.addEventListener("backbutton", function(){
if(is_swal_open){
close_swal_dialog();
return false; // NOTE: i expected this should prevent from go to previous page
}
});
},
}
What you can do is warn the user:
if(is_swal_open)
{
window.onbeforeunload = function() { return "Your warning here."; };
}
or add an event listener like so:
window.addEventListener('beforeunload', function (e) {
if(is_swal_open)
{
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
}
});
I´m having a hard time understanding what am i missing here when the user receives a push notification and then hits the button in order to see it and navigate to the proper page inside the app, so my code is this and by the way it works very well in ios:
So if the application is android, i use this code below... i receive the content and pass it to a function called handleOpenURL
if (application.android) {
application.on(application.launchEvent, (args) => {
try {
TnsOneSignal.startInit(application.android.context).setNotificationOpenedHandler(new TnsOneSignal.NotificationOpenedHandler({
// notificationOpened: function (result: com.onesignal.OSNotificationOpenResult) {
notificationOpened: function (result) {
const imovelAndroid = JSON.parse(result.stringify()).notification.payload.additionalData;
handleOpenURL(imovelAndroid);
}
})).init();
TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification);
TnsOneSignal.startInit(application.android.context).init();
}
catch (error) {
console.error('error', error);
}
});
}
I´m actually entering the function below, but the problem is when navigating, it simply does not work:
function handleOpenURL(argImovel) {
const precoToNumber = +argImovel['imovel'].preco;
const precoFormated = Number(precoToNumber).toLocaleString("pt-PT", { minimumFractionDigits: 0 });
const navigationOptions = {
moduleName: "detail/detail-page",
context:{ //my context here which is big so i´m not putting it.
}
};
frameModule.topmost().navigate(navigationOptions);
}
Everything works as expected in ios, it is suppose to receive the push, and when the user hits it, the app should navigate to a detail page where the content receive is showned.
What am i missing? thanks for your time, regards.
EDIT
Thanks to Manoj, i fixed the issue adding this to my handleOpenURL function:
setTimeout(() => {
frameModule.topmost().navigate(navigationOptions);
}, 2);
Make sure your Frame is ready for navigation, try logging frameModule.topmost() and see if that is a valid frame.
May be you could try a timeout of 1 or 2 secs and see whether that fixes the issue.
In my application, I am using actions to do all of my ajax calls. When the results come back, it dispatches them to the reducer, which then puts it in the store. My component is bound to the property and will then be able to get it from the store.
However, I am having an issue trying to figure out the best way to do form submissions. From a listing page, a user can click on a link from any row to open a modal. This modal has a form in it. When the form is filled out, it will then pass the data along to an action, which will submit it. The only response from a valid submission is a HTTP 200.
Without using callbacks, how would the modal know that the ajax call is complete, so it can close itself? As of now, I have a flag in the store called form.processing. This is default to false, and the action will set it to true when it begins and false when its done. The component watches this and then knows when it goes from true to false and knows everything is done. However, I feel like there should be a better way.
Or should I be using callback in forms, even though we don't follow that process for any other ajax call?
Here are following pseudo code can help you:
constructor () {
this.state = {
disaplyModalPopup: false;
}
}
handleSubmit = () => {
this.setState({disaplyModalPopup: true})
let payLoad = { 'Key':this.state.something }
this.props.hitAPI(payLoad).then((res) => {
if (res.data.success) {
this.setState({
'disaplyModalPopup': false
})
}else{
this.setState({
'disaplyModalPopup': true,
'errorMessage': 'something wend wrong'
})
}
})
}
rendor (){
let errorMessage = {this.state.errorMessage}
let disaplyModalPopup = {this.state.disaplyModalPopup}
return (
{disaplyModalPopup ? <modal> </modal> : ''}
{ errorMessage? 'errorMessage': ''}
)
}
Here I have handled your modalPopup with disaplyModalPopup state.
And After get in the response saved in reducer, it is changes as {disaplyModalPopup: false}
And modalPopUp HTML will disappear.
But in case your API get in failed while making response.
So that case: i have handle as error message in as text
errorMessage where you can show your error message. So that Modal is closed side by side.
on website I have sometimes additional button with restoring autosaved data filled in the form, which pops in random moments (sometimes someone tests something and close form, which causing the popup button). I tried with Continue if element is not visible in protractor with following code:
let DoNotRefillBtn=element.all(by.className('modal-button-no'));
var isApproachable = function(element) {
return element.isPresent().then(function (present) {
return present
? element.isDisplayed()
: false;
});
};
describe(...)
it('Open the form:', function () {
browser.driver.get('foo');
browser.sleep(1000);
isApproachable(DoNotRefillBtn).then(function(approachable) {
if (approachable) {
DoNotRefillBtn.click();
browser.sleep(500);
}
else {
browser.sleep(300);
}
});
It clicks correctly, but after clicking, it throws error Failed: element not visible on line DoNotRefillBtn.click();.
Why does the program clicks and throws an error that thing is not clickable (after it was clicked)?
I used a workaround, the button comes with the status message "Do you want to refill the form?". So when I check for the status message and click the button, seems to be working:
let StatusMessage=element.all(by.className('status-message'));
let DoNotRefillBtn=element.all(by.className('modal-button-no'));
var isApproachable = function(element) {
return element.isPresent().then(function (present) {
return present
? element.isDisplayed()
: false;
});
};
describe(...)
it('Open the form:', function () {
browser.driver.get('foo');
browser.sleep(1000);
isApproachable(StatusMessage.get(8)).then(function(approachable) {
if (approachable) {
DoNotRefillBtn.get(0).click();
browser.sleep(500);
}
});
});
});
StatusMessage.get(8) is 8 because there are some more messages with the same class, but not displayed. I counted which status-message is that one and it seems to be working - closes popup if displayed, but skipping when it's not.
Propably checking the button and clicking it gives some problems
I am using following code to let the user log into Magneto with AJAX. If the correct username and password is entered the page will refresh and display the user navbar in the header. The field works in Firefox, Safari and IE but not in Chrome. I have to refresh the page for the navbar to display.
Why does this problem occur?
Code:
AjaxLoginForm.submit = function(button){
if (this.validator.validate()) {
// show ajax image
// button.insert({"after":osc_ajax_loading_small});
AjaxLoginForm.hideLoader();
AjaxLoginForm.insertLoader(button);
$("ajaxlogin_form").request({
onSuccess: function(transport) {
var json = transport.responseText.evalJSON();
if(json.is_forgot_pwd){
if(json.success){
$("ajaxlogin_form_message").update("<div>"+json.success_message+"</div>");
$("ajaxlogin_form_message").show();
}
if(json.error){
$("ajaxlogin_form_message").update("<div>"+json.error_message+"</div>");
$("ajaxlogin_form_message").show();
}
}else{
if(json.success){
// If the correct username and password is entered
// the page will refresh and display user navbar
// in the header
window.location.reload();
}
if(json.error){
$("ajaxlogin_form_message").update("<div>"+json.error_message+"</div>");
$("ajaxlogin_form_message").show();
}
}
AjaxLoginForm.hideLoader();
//setTimeout("AjaxLoginForm.hideResponseMessage()", 5000);
}
});
}
}.bind(AjaxLoginForm);
You can try it with a setTimeout.Also you can simplify the code,currently you are writting json.success and json.error multiple times which should be written once.
setTimeout(function(){
window.location.reload();
},100);
try this, I am preety sure in chrome window.location = self.location; should work, or try location.reload( true ); otherwise by callback some other function to reload your page.
Otherwise you should get some error that prevents reload, you can get a console in success.
For script is in iframe top.location.reload() works for me.