Selenium IDE - timing of chooseOkOnNextConfirmation during page forward - javascript

I'm trying to book a table at a restaurant. After I click on the book button, the page forwards, checks back to confirm availability with the server (over the course of maybe 2 seconds) and then opens a JavaScript confirmation pop-up in the browser.
Will I be fine with chooseOkOnNextConfirmation before I press the button and thus before the page forwards or should I add another (or move) chooseOkOnNextConfirmation after the click during the availability check?
Would it hurt to have several chooseOkOnNextConfirmation commands in a row? Would they interfere with each other?
It is essential that I get the timing right. Too early and the command might be executed on the wrong page, too late and the JavaScript pop-up stops my script. Please note that I can not test the script nor can I look at the page's JavaScript properties as bookings are closed right now and will only be available later.
Alternatively, should I use clickAndWait instead of click (the URL doesn't change though and the command may cause errors)? Can I use assertConfirmationPresent to determine whether the page is fully loaded before assertConfirmation or will it be too late since the pop-up already stopped my script?
What I have for now looks as follows:
chooseOkOnNextConfirmation
click //*[#id="table_id"]/thead/tr/th[1]/input
assertConfirmation glob:Are you sure you want to submit your request
for the following unit: Location Description:*
Btw, turns out globbing doesn't work for the command assertConfirmation. I get the error Confirmation message doesn't match actual message in the log unless the text in target matches the text in the pop-up exactly. Any ideas how to work around or how to make glob:* work?

Related

How to run popup.html without using default_popup? (CHROME EXTENSION)

So, I've got a situation where I want a background and content script to be run everytime the browser extension icon is clicked. The ideal behaviour is that extension icon is clicked, the script runs, and the popup will open, displaying the data that was grabbed by the script (but this should happen quickly, the script runs and gets the data very fast). Since chrome.pageAction.onClicked will not work if there is a default_popup defined in manifest.json, I think this leaves me with two options:
Use default_popup and figure out that the extension icon has been clicked some other way. I found this solution in another stack overflow post, but the workaround is to use default_popup: "popup.html", and then the popup.js that is defined in popup.html will send a message saying that the icon has been clicked, then when background.js receives this message, it executes the script. I implemented this idea and it worked... kinda. The trouble is, the popup will always come up before the script is fully executed, so you can't actually display the data grabbed by the script in the popup until the next click. I'm not sure there's any way to get the behaviour I desire using this method, so on to the next:
The other solution I can possible think of is to use onClicked, and then make the popup come up some other way, besides using default_popup in manifest.json. I'm also not sure if this is possible, I have looked on stackoverflow and haven't found anything similar.
Is the second method possible? Can the first method work somehow?
Your option #1 is correct, I think all that is needed is a loading screen when the user first sees the popup, and add some code that updates the popup as soon as it hears from the backend. Might need to see some code to better help there.
Option #2 will not really work, unless you opened the popup in a new tab (or just made it a whole new HTML page). I say this because there is a note here from the Chrome Dev team they will not support opening a popup unless it is from a user gesture -- https://stackoverflow.com/a/10484764/4875295.
If you wanted to go that route it would probably look something like:
Delete from your manifest.json browser_action.default_popup
In your background script add something like:
chrome.browserAction.onClicked.addListener(() => {
const data = dataMaker();
chrome.tabs.create({
url: `${chrome.runtime.getURL("app.html")}?data=${data}`
});
});
Then in your html file have some JS that reads the query string and updates the page accordingly.
Though, that's a different approach than you asked for and I think your original route may still be the best bet (with some added JS around loading).

Change back button behaviour of browser

Posting without a target so that a web page reloads seems useful behaviour for some things - such as writing a login page. I have implemented a calendar in PHP which takes advantage of this. It reloads an object from the session (or creates a new one if not present), applying any changes that result from the post then saves the object back to the session. The problem is this. If I hit the back button I don't want to go back through every click of the calendar button but would rather jump back to the page before arriving at the calendar page. Not only that, if I do go back one calendar page after another I get an annoying "confirm form resubmission". I have implemented an incrementing value after the # for each post so that I might be able to use window.onhashchange. The problem is that window.onhashchange never fires so I am unable to intercept the back button and pop the history stack. Any ideas? Am I better off coding on the server side with javascript?
Well I solved one problem. My form subclass in PHP defaults to using POST as I understand this is more secure. This causes the annoying resubmission problem when using the back button. I now use GET in my calendar page which solves this issue. I am still bemused by JS debugging in Netbeans. I have never got script to stop on a breakpoint within a single document. I have previously had it working with an external javascript source but this no longer works. If I can output to console but there is no window in which to see the output. I am told window.alert no longer works for some events in Chrome. I am completely blind! To add to the irritation, it took me a while to realize was that the javascript file was cached and changes would not be reflected in behaviour. I have put a random number into the script tag which fixes this issue. As I am debugging using netbeans connector in Chrome I have no idea why this does not force the js file to refresh. All in all, this appears to be a pretty shambolic toolchain.

What is the proper way of preventing user interaction while downloading a file?

Ok so this is a general question about browser interaction and HTTP mechanims
Here is the scenario
There is a very rich interface with a lot of buttons.
The user clicks the button "generate the report"
Then there is a loading time of approximately 15 seconds and then the "save file" dialogue box appears
The user saves the files wherever he wishes and do further stuff.
Now I want to:
Prevent him from interacting with the interface during step 3.
At the end of step 3, trigger some specific javascript like showing a popup.
All this actually sums up to "how to detect the appearance of the download dialog box in javascript" because once this one is solved, this is easy to set up some mask during the file generation, and to do whatever is required once the event has been detected.
Unfortunately it seems like there is no way to launch a file download via Ajax because it lacks adequate handling for turning an XMLHttpRequest into a save as dialog box. As a consequence you need to submit some form, but the mechanism is a little weird because although you submitted the form absolutely nothing happens in the DOM. Then the browser detects that response to the form submission is an incoming file and shows a download box instead of trying to display the file content, and once the user is done with the download box, the browser somehow manage to restore the interface in its previous state so that the user can keep on browsing (or at least this is how I understand the thing).
Display a loading sign for x seconds, disable click events (see here) or replace them with a dialog saying they should stay quiet while it loads. Do not forget to make the loading sign moving/showing progress or they will get bored. I'm sure there are plenty of libraries to achieve this, you could even try using the <'progress'> tag. As #j3r3m7 said, if they want to close the browser they will; the goal here is to make user understand he has to wait for x seconds and make him eager to wait.
As for your other issue, please look here
EDIT : A helpful plugin to address these kinds of issues can be found here.
Interesting question as in essence you can't stop the user from doing anything really... they could if so inclinded:
close their browser
enter a url directly to go to a new page
click back in the browser
open a new browser window and navigate to the report generation page for a second time
refresh the page
So, if you have a long running process quite a good way to deal with it is:
indicate that the process may take a while
at the point that the report is ready provide a unique link to the generated report
if you are using a javascript framework like AngularJS you could asynchronously handle an event that shows a report download/view link when the report is ready.

Opening a new window using Javascript after a timeout caught by popup blocker

I'm having a situation in which I want to allow the user to download a PDF. The generation of this PDF can take a couple of seconds, and I don't want a webserver thread to wait for the generation of the PDF, since that means the thread isn't available to handle other incoming requests.
So, what I would like to do is introduce the following URL patterns:
/request_download which invokes a background job to generate the PDF;
/document.pdf which will serve the PDF once it is generated
The use case is as follows.
A user clicks on 'Download PDF'. This invokes a piece of Javascript that'll show a spinner, make a request to /request_download and receive a HTTP 202 Accepted, indicating the request was accepted and a background job was created. The JS should then poll the /request_download url periodically until it gets HTTP 201 Created, indicating that the PDF has been created. A Location header is included that is used by the JS to forward the client to /document.pdf. This has to be in a new window (or tab, at least it shouldn't replace the current page). The level of expertise of our users is very low, so when I forward to the url, they might not know how to get back to the website.
The problem
Now, window.open works fine if it is invoked by the user via a click event. However, I want to invoke window.open in a callback function through setInterval as soon as I see that 201 Created response. However, browsers won't like that and will interpret it as a popup, causing it to get caught by popup blockers on IE8-10 as well as Chrome. Which makes sense.
I also can't open a new window and invoke the Javascript over there. In that case, users would see a blank page with a spinner. If that page then forwards to the /document.pdf, IE will show this yellow warning bar telling that it prevented files from being downloaded. Chrome and Firefox will do this without any problems, but a large percentage of our users is on IE.
What I've tried, and didn't work
window.open(location)
Setting the src of an iframe to the retrieve location
Manually adding an <a> tag to the document body and trying to click it using javascript
Adding an <a> tag to the document body and invoking a MouseEvent on it
Partially works: opening a new window on user click and storing a reference to it, then perform the asynchronous requests and upon completion, set the location of the earlier opened window. But: IE will block this and say it prevented files from being downloaded. So still not a fully working solution.
I'm straight out of ideas on how I can make this work and decided and decided to ask The Internet for help. I'm hoping you guys can help me with this, or recognise the problem. Thanks in advance!

Prevent any form of page refresh using jQuery/Javascript

Once the user is on my page, I do not want him to refresh the page.
Anytime, the user hits F5 or refresh button on top. He should get an alert saying
You cannot refresh the page.
Also if the user opens a new tab and tries to access the same url in prev tab he should get an alert
You cannot open same page in 2 tabs
Anyway I can do this using JavaScript or jQuery? Point one is really important.
#1 can be implemented via window.onbeforeunload.
For example:
<script type="text/javascript">
window.onbeforeunload = function() {
return "Dude, are you sure you want to leave? Think of the kittens!";
}
</script>
The user will be prompted with the message, and given an option to stay on the page or continue on their way. This is becoming more common. Stack Overflow does this if you try to navigate away from a page while you are typing a post. You can't completely stop the user from reloading, but you can make it sound real scary if they do.
#2 is more or less impossible. Even if you tracked sessions and user logins, you still wouldn't be able to guarantee that you were detecting a second tab correctly. For example, maybe I have one window open, then close it. Now I open a new window. You would likely detect that as a second tab, even though I already closed the first one. Now your user can't access the first window because they closed it, and they can't access the second window because you're denying them.
In fact, my bank's online system tries real hard to do #2, and the situation described above happens all the time. I usually have to wait until the server-side session expires before I can use the banking system again.
You can't prevent the user from refreshing, nor should you really be trying. You should go back to why you need this solution, what's the root problem here?. Start there and find a different way to go about solving the problem. Perhaps is you elaborated on why you think you need to do this it would help in finding such a solution.
Breaking fundamental browser features is never a good idea, over 99.999999999% of the internet works and refreshes with F5, this is an expectation of the user, one you shouldn't break.
Although its not a good idea to disable F5 key you can do it in JQuery as below.
<script type="text/javascript">
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
$(document).ready(function(){
$(document).on("keydown", disableF5);
});
</script>
Hope this will help!
Back in the ole days of CGI we had many forms that would trigger various backend actions. Such as text notifications to groups, print jobs, farming of data, etc.
If the user was on a page that was saying "Please wait... Performing some HUGE job that could take some time.". They were more likely to hit REFRESH and this would be BAD!
WHY? Because it would trigger more slow jobs and eventually bog down the whole thing.
The solution?
Allow them to do their form.
When they submit their form... Start your job and then direct them to another page that tells them to wait.
Where the page in the middle actually held the form data that was needed to start the job.
The WAIT page however contains a javascript history destroy. So they can RELOAD that wait page all they want and it will never trigger the original job to start in the background as that WAIT page only contains the form data needed for the WAIT itself.
Hope that makes sense.
The history destroy function also prevented them from clicking BACK and then refreshing as well.
It was very seamless and worked great for MANY MANY years until the non-profit was wound down.
Example:
FORM ENTRY - Collect all their info and when submitted, this triggers your backend job.
RESPONSE from form entry - Returns HTML that performs a redirect to your static wait page and/or POST/GET to another form (the WAIT page).
WAIT PAGE - Only contains FORM data related to wait page as well as javascript to destroy the most recent history. Like (-1 OR -2) to only destroy the most recent pages, but still allows them to go back to their original FORM entry page.
Once they are at your WAIT page, they can click REFRESH as much as they want and it will never spawn the original FORM job on the backend. Instead, your WAIT page should embrace a META timed refresh itself so it can always check on the status of their job. When their job is completed, they are redirected away from the wait page to whereever you wish.
If they do manually REFRESH... They are simply adding one more check of their job status in there.
Hope that helps. Good luck.
No, there isn't.
I'm pretty sure there is no way to intercept a click on the refresh button from JS, and even if there was, JS can be turned off.
You should probably step back from your X (preventing refreshing) and find a different solution to Y (whatever that might be).
Issue #2 now can be solved using BroadcastAPI.
At the moment it's only available in Chrome, Firefox, and Opera.
var bc = new BroadcastChannel('test_channel');
bc.onmessage = function (ev) {
if(ev.data && ev.data.url===window.location.href){
alert('You cannot open the same page in 2 tabs');
}
}
bc.postMessage(window.location.href);
Number (2) is possible by using a socket implementation (like websocket, socket.io, etc.) with a custom heartbeat for each session the user is engaged in. If a user attempts to open another window, you have a javascript handler check with the server if it's ok, and then respond with an error messages.
However, a better solution is to synchronize the two sessions if possible like in google docs.

Categories

Resources