How do I programmatically login through Auth0 Lock interface? - continuous-integration

I'm trying to write a WebPageTest custom script that involves programmatically logging into my web app's Auth0 Lock interface as the first step but haven't been able to get it working.
I set up a private WebPageTest server to get a closer look at what was happening, and from the server logs it looks like the WebPageTest script is setting the value of the username/password fields and clicking submit using vanilla DOM manipulation (i.e. querySelector, click, etc.) but upon form submission, Auth0 Lock doesn't recognize that anything has been filled out in those fields. There's errors saying those fields can't be blank when submit is clicked.
I've used a local WebPageTest Node agent with my private server to successfully login through the Lock widget but don't know how to get performance logs using that approach (no results show after I get to the test results page). That login approach seems to work because the values going into the input fields get programmatically "typed in" through the WebDriver sendKeys function.
I came across this related post on Auth0 forums but don't know how I can incorporate what's being recommended there in the context of a WebPageTest script.
You can reproduce the problem I'm experiencing by going to the Auth0 Lock sample at the top of this page and running the following code in your devtools console:
document.querySelector('.auth0-lock-input[name=email]').value = 'hello#hello.com';
document.querySelector('.auth0-lock-input[name=password]').value = 'testing';
setTimeout(() => document.querySelector('.auth0-lock-submit').click(), 1000)
I expect to be able to programmatically enter input field info and submit it through the Auth0 Lock widget but haven't been able to do so. Does anyone have a solution to this?

The login page uses javascript/ajax to create the login form and its input elements. You're simply doing stuff too fast, not waiting for the elements to be created first, in order to populate and submit them. Just wait for the form and its input elements to become available/visible and then continue your login process.
Also, avoid using Sleep() / setTimeout() approach to tackle waitings. It's just wrong and it's a problem waiting to materialize itself, as soon as you change the environment in which your code is running. Use a proper waiting methods from your test framework and properly wait for those elements to become available.

Related

Cypress test fails but works when tested manually

I am trying to test the ability to retrieve results from a database. When running a test that logs in, navigates to the search tab and searches a word, I am getting a 401. If I go to the website, use the same log in information and do the exact same steps, it works perfectly. Here's the last few steps of the test:
cy.contains('Search').click(); //open tab
cy.contains('Search by').click();
cy.contains('Name').click();
cy.get('.search-field').type('Jane');
cy.get('.search-btn').click();
There's a drop down menu for what you want to search by, a textfield for the search word and a search button. I can't share all of the code but I can see from the video that logging in and all the following steps are performed as supposed to. What kind of things can cause a cypress test to return different results as opposed to manually performing the action? I added wait(2000)'s in between the steps but it made no difference.
Maybe there is an event that needs to be triggered before the page is able to search.
Take a look at the element you are typing into in the devtools, under the Event Listeners tab.
For example, the StackOverflow search box has an event for s-popover:show listed there - if testing that you would .trigger('s-popover:show') to fire that event and display the instruction tooltip.
So try something like this
cy.get('.search-field')
.type('Jane')
.trigger('change') // or .trigger('input')
Cypress deletes localStorage in between tests. In this case that deleted the authorization token which is why I was getting the 401. I installed this package: https://www.npmjs.com/package/cypress-localstorage-commands
After the log in I use
cy.saveLocalStorage();
And before making search
cy.restoreLocalStorage();

Programmatically determine if Sagepay card details form is incomplete

I'm looking for some help with regards to the drop-in checkout integration.
https://developer-eu.elavon.com/docs/opayo/integrate-our-drop-checkout
In particular I'm following ‘custom flow’ example - see first code example for the Custom Flow section. https://developer-eu.elavon.com/docs/opayo/spec/api-reference#section/Custom-flow
In summary how can I programmatically determine if the sagepay 'card details' form which is injected into the sp-container (hosted in an iframe) is not valid for submission/tokenisation, when a call ‘tokenise’ link is used?
For example when the user has not completed all the required fields; Name, Card Number, Expiry or CVC.
I'm following the flow calling sagepayCheckout.tokenise() when the user clicks our 'Complete Payment' button (referred to as the tokenise link in the custom flow example).
NB: Implementation is part of a SPA app in my particular case I'm not submitting the (outer) form rather handling things using javascipt and calling the tokenise method.
Normally the onTokenise call back method is called on success or when wrong card details have been entered or merchantKey has expired. But when the injected sagepay form fails its own validity the onTokenise call back is never called.
NB: Due to browser security I can't check the state of the fields inside the iframe.
Ok some good points to note:
The sagepay form does feedback to the user about errors that required fields need to be completed.
And sagepayCheckout.tokenise() doesn't try to submit my (outer) form when these errors exist.
But there doesn't seem to be a programmatic way to know if the required fields need to be complete (or the onTokenise call back wont be called).
The main reason I need to know when the form is incompleted or tokenise has failed would be to re-enable our 'Complete Payment' button. Currently our button is disabled as soon as the user clicks it to prevent multiple clicks.
I am having this exact same problem. The only way I have been able to think of to get around this is to use the message event listener on the window. The sagepay.js library registers a 'message' event on the window object probably when the sagepayCheckout method is called.
Side note: this method is also poorly implemented as anything else that uses the window message event will cause the sagpay.js library to throw errors.
I think the only purpose of sagepay.js' message event hander is to resize the iframe window when its content changes. If you were to assume the content of the iframe will only change when validation fails you might be able use that to reset the state of your 'Complete Payment' button.
I would also suggest making a complaint to Opayo. This library is clunky and in desperate need of improvement.

Is it possible to get another person's UI in Google Apps Script?

In Google Apps Script when you use the property: DocumentApp.getUi(), it gets the UI of the person who is using it. If you used DocumentApp.getUi().alert(), then it would send an alert to the person who is using the script. I am wondering if there is maybe a way to alert another person's UI in Google Apps Script and not the person who is using the script. Here is a sample of my code:
DocumentApp.getActiveDocument()
.removeViewer(userName.getResponseText())
.removeEditor(userName.getResponseText());
DocumentApp.getUi()
.alert("Your access is being removed.")
Now it would be wonderful and imagine all the possibilities if that were possible! Someone please help!
It is not possible to access the UI of any browser except the one which invoked the function. This is also why time driven triggers cannot display UI modals (they are executing nonlocally).

strutrs2 and ajax(Displaying dynamic value on jsp)

Im pretty new to struts2 and Ajax ,Actually i have a drop down menu in JSP lets say first.jsp, When user select a choice from dropdown menu,I am calling a function of Action class lets say Method1.In this method i am fetching some value from DB(lets say:a,b,c) and one value from java memory lets say d.Then I am forwarding to second.jsp and display all the parameters(a,b,c and d) in tabular format.
Now problem is that the parameter d is dynamic ,this is updating by some other application and if its change then I have to show it on JSP wihout any action.
One solution is I use in second.jsp , so after interval of 10 second again Mehod1 will call and it will fetch value(a,b,c) from db and updated value of d from java memory. and disply it to second.jsp.But in this case i am unnecessary retrieving value from db while my purpose is just to get value d from memory.This is working but this is causing my application to slower.
Can any body suggetst some other solution? or can i do it using ajax and how?
Any other advice? any help is appreciated.try to be more clear, i'm in lack of ideas in this problem, even it sounds like a classic :I have spend hours trying to play around with this but have got nowhere
Okay... What you're asking is a little fuzzy so let me rephrase:
You have a user (USER1) who opens a web page and sees some data.
You have a second user (USER2) (who may be an application) who is able set a value from time to time.
When USER2 updates that value you want USER1 to see it change in their open browser window?
If this is the case you need to understand basic ajax. For that get these demo applications working:
This example uses dojo and perhaps the S2 ajax tag lib I don't remember I prefer not to use ajax tags (as they are deprecated and prefer jquery for ajax):
http://struts.apache.org/2.x/docs/struts-2-spring-2-jpa-ajax.html
This example here shows a very similar application but using jquery, no tag library, upgraded to Spring 3, it still needs polish:
http://www.kenmcwilliams.com/Downloads/
Now that you know how to get data via ajax, look at the request with firebug. You'll see that the request is just like a typical function call, the browser keeps waiting for the data to come back.
What you do is simply not return from the action until new data is provided. This is called long polling see: http://en.wikipedia.org/wiki/Comet_%28programming%29#Ajax_with_long_polling
If you have not written a simple chat program, using just terminal windows I recommend you do so. Two windows per client (client-send, client-receive windows) and you'll need a server program. I remember hacking one together in a few hours using _Thinking In Java 2nd Edition (Later books took out the networking section if I remember correctly). Anyways between understanding client server interaction and long polling will let you get things working. It would be fun to extend the simple terminal based chat application to a S2 ajax chat application. Would make an awesome tutorial! PS: This is just an application of the producer/consumer problem (If you understand that then I guess you don't need to do the fun exercise).
The interfaces would look very pretty if the server was managed by spring. I know there must be nice servers already written but I am not familiar with any, but would love to hear of one.

In CakePHP 1.3 is there any advantage of using $this->Controller->Session over $this->Session in a component?

I'm using a modified version of Felix Geisendörfer's SimpleAuth/SimpleAcl components that I've combined into a single Component, Simple_Authable.
I changed his startup() function to initialize() to not clutter the beforeFilter function in my app_controller.
One of the things that this component does is check who the active user is and if that user can't be found it either looks him up based on the primary User.id or uses 'guest'. Either way, the component uses $this->Controller->Session->write() to save the active user or guest information.
I'm also using Felix's Authsome plugin instead of the default CakePHP Auth component.
When I'm logging in, the active user is guest, obviously.
After I've submitted the form, the active user is still guest because the component's initialize() function is firing before everything else. Then, the Authsome plugin comes into play and validates my user as "root" and also calls $this->SimpleAuthable->setActiveUser($id, true); to force SimpleAuthable to update the active user information it is storing via $this->Controller->Session; Then I am redirected and my simple Session information and DebugKit's Session tab reflect that I am indeed the root user.
However, when I try to navigate to an 'admin' page, let's say /admin/users/index, lo and behold SimpleAuthable thinks I'm still a 'guest' user because when it performs a $this->Controller->Session->read() call to the key holding my user id, it is getting an empty response, i.e., the data stored on the previous page didn't persist.
Maybe there is something funky happening between Authsome & SimpleAuthable, but things look pretty straightforward and to my mind, $this->Controller->Session should be saving and persisting the data written to it.
So, I'm looking at refactoring all the calls to $this->Controller->Session and replacing them with $this->Session but first I wanted to throw this out to the community and see if anybody has seen anything similar and if so how did they resolve it.
Sincerely,
Christopher.
I found the problem... I'm also using Joshua McNeese's Permissionable plugin and I needed to disable it for the $this->Controller->{$this->userModel}->findById($id); in my SimpleAuthable component when I try to lookup the current active user.
Note to self: I would have caught this faster if I had some unit testing in place :(.

Resources