I'm using selenium webdriver to do some downloading using firefox. At the moment my script waits for a specific time after download has inititated and then close the firefox. I want to know if there is a way to configure firefox to automatically close on download completions? Or using selenium webdriver, can I check if download has been completed? I don't want to use any add on, as it might add dependency in my script. I cant use wget/curl etc to download the files.
Thanks in advance
What Ignacio Contreras said. Polling the download path is possibly the best (most robust) solution.
Alternative #1:
Use a FirefoxProfile with Download Statusbar addon. It has a handy option to "Continue downloading in Download manager after window has been closed" (or something very similar), so that it will keep Firefox running in the background until the download has been finished.
Alternative #2:
Download the file directly using this (or any other similar WebDriver-friendly tool) ... or this, if you can. That will totally cut Firefox out of the process.
You can use Selenium WebDriver API's WebDriverWait class to do the polling using the following code:
(new WebDriverWait(driver, 180, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return !downloadedFilePart.exists();
}
});
The above code checks for file with .part extension program is downloading for every 10 seconds until either download completed or timed out after 3 minutes.
I'm not sure if this would work, but have you considered exploring trhough Firefox the download location? polling it until you see the download has been completed.
If I'm not wrong, when the file it's been downloaded, there should be an extra file with the extension .part.
Something like this (pseudocode):
...
WebDriver poller = new FirefoxDriver()
poller.get("path to download folder");
while ("file with .part extension is present") {
// Wait/sleep some time
// Refresh poller
}
// close downloading firefox instance
firefox.quit();
// close the polling instance
poller.quit();
Hope it helps
Related
I use my WebDriver, with FireFox.
I have an elemnt: //input[#class="uploadFiles"], when I click on it by:
driver.findElement(By.xpath("//input[#class="uploadFiles"]")), a windows of upload a file (Windows OS's window) is opened, but the test doesn't continue to the next line, and get stuck.
Any help?
Webdriver doesnt interact with os level dialogs and that's the reason it doesnt continue to the next line. Here's something to help you : http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_Does_WebDriver_support_file_uploads?
No you cant do it with WebDriver as niharika_neo answer but you can do next:
string filepath = "my local path";
_driver.FindElement(By.Id("attachments")).SendKeys(filepath);
_driver.FindElement(By.Id("attachments")).SendKeys(Keys.Return);
You can't interact with OS level Windows directly. You can go through the path given by niharika_neo or else you can use Auto IT tool for handling the OS level windows. The best option is to use Auto IT tool.
I faced the same problem with FF, then I found that it was specific to the FF version I am using. I installed and ran the tests on FF 11, and I was able to successfully runt he tests. Try changing the version of FF that you are using.
I want to save user settings for my firefox add-on in a variable which can be accessible any time I want. It should not get vanished on browser clos. Now how can I do it?
I have tried "simple-storage" module of firefox, it works fine until I quit my browser. When I quit my browser, "simple-storage"s wipes out. So I can't use it.
I have also tried "io/text-streams" module but when I try to use this module in "firefox add-on builder"
var io = require("io/text-streams");
io.write("write it");
I am getting this error:
XPI not built
ModuleNotFoundError: unable to satisfy: require(io/text-streams) from /tmp/tmpePRdMr/addon-sdk-1.12/packages/sadaf2605-4/lib/main.js:2: Looked for it in: /tmp/tmpePRdMr/addon-sdk-1.12/packages/sadaf2605-4/lib/io/text-streams.js /tmp/tmpePRdMr/addon-sdk-1.12/lib/io/text-streams.js
Most probably, I would need to install some packages, do the user who will be using my add-on, do they also need to install those packages on their browser?
Apparently you are testing your add-on with cfx run. The documentation explains why simple-storage appears broken and how to solve it.
Try saving your settings in localStorage object (HTML5) .Your values wont vanish after the session is closed ......
Since updated to Firefox 12, every time I launch Firefox with a particular profile with Selenium (in python and Mac OS 10.7) it pops up the "checking compatibility of add-ons" dialog, and sometimes this dialog would stay up forever and I have to force-quit it. After forcing quit it, a new instance of the Firefox would continue to launch and finishes the rest of the Selenium script successfully though.
I have tried setting extensions.checkCompatibility to false. This fixed it if I launched Firefox normally, but not if I launch it with Selenium. Any idea on how to suppress this dialog? Thanks!
This dialog is shown only once whenever Firefox is updated. The reason it is shown each time for you is probably that Selenium creates a new profile each time. If you set extensions.lastAppVersion preference to "12.0" (or whatever the current Firefox version is) then Firefox will no longer think that it has been updated and won't show this dialog. However, it should be easier to add a extensions.showMismatchUI preference and set it to false, this will suppress this dialog (but not the other upgrade actions).
Side-note: extensions.checkCompatibility preference no longer does anything starting with Firefox 3.6, it is a version-specific preference in the current Firefox versions. So you would have to set extensions.checkCompatibility.12.0 preference instead. That disables compatibility checking for extensions completely however, not just the dialog you are concerned about.
I have tried setting extensions.checkCompatibility to false. This fixed it if I launched Firefox normally, but not if I launch it with Selenium.
The reason it won't when you launch it with Selenium is the Firefox Driver will create a temporary profile in the temporary files directory, slowing down tests and taking up unnecessary space.
Create a profile for your test purposes and set what you need. Full instructions to create the SeleniumProfile can be found at https://support.mozilla.org/en-US/kb/profile-manager-create-and-remove-firefox-profiles
In Java I have the following:
protected WebDriver createFirefoxDriver() {
File proFile = new File("C:\\Users\\<username>\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\xxxxxx42.SeleniumProfile");
FirefoxProfile ffProfile = new FirefoxProfile(proFile);
WebDriver ffDriver = new FirefoxDriver(ffProfile);
return ffDriver;
}
Do this to remove the "checking for addon's compatibility" Dialog. This is based on the Windows operating system..
Create a temporary FF Profile and start the server with that profileas shown below.
java -jar selenium-server-x.x.x.jar -firefoxProfileTemplate "/path/to/the/temp/profile"
Now use the following code.
import com.thoughtworks.selenium.*;
public class Test {
public static void main(String ar[]) {
Selenium sel = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
sel.start();
}
}
Now in the Run command type "%TEMP%" and you can see there a folder with same name as the selenium session. Copy the folder contents and replace them with your temp profile Contents.
Follow the steps below to remove the Addons compatibility.
1 . Create a new FF Profile
2 . Set the FF Profile as per required settings
3 . Just run a sample program of selenium such that it invokes firefox.
4 . Now you can find a folder with the same name as Selenium Session created somewhere in your sytsem. ( Most probably in the directory where the Temporary Content is saved)
5 . Copy the folder contents and replace them with the newly created profile.
Now you can use the newly created profile whenever required. Whenever FF is updated , always check whether the existing addons are compatible with the Existing version by once invoking firefox with the Profile.
I need to create/update/remove cookie for FireFox browser. This cookie is a client cookie, as in it has to be created by C++ executable and it will be present on the end user machine.
How can I achieve this?
Thank you
You basically have two options:
You attempt to manipulate Firefox data (file cookies.sqlite) directly. It's a fairly simple SQLite database so there is nothing complicated about that. However, catch 1: this cannot be done while Firefox is running. Also, catch 2: the format might change in future (as happened before) and your application will stop working or, worse, break the file.
You do it from inside Firefox. For example, you would write a bootstrapped extension that would use nsICookieManager2 interface to add the cookie and then Add-on Manager API to uninstall itself immediately after that. Then your application would only have to run Firefox with the command line firefox -url file:///path/to/extension.xpi (works even if Firefox is already running). The catch here: the user would need to confirm extension installation. So you cannot do it behind his back, you need to explain what is happening and why.
I didn't find a way to debug Greasemonkey scripts with the Firebug extension.
Does anyone know how to do this ?
Thanks.
Updatier: The Mene+Shuman fix now is busted with Firefox 30 and Firebug 2. Firefox 31 may provide workarounds (will investigate). In the meantime, use the "General workaround strategies" listed below.
Update: This answer is now obsolete.
If you open about:config and
set extensions.firebug.filterSystemURLs to false
then you can use Firebug to debug the Greasemonkey script just like any other.
This works irregardless of the #grant mode.
See Mene's answer -- with an assist from Shuman.
Old answer:
Because Greasemonkey operates in a sandbox, Firebug cannot see it. There is no easy way around this.
General workaround strategies:
Test all parts of a GM script that don't use GM_ functions, in Firebug's JavaScript console first. Minimize use of GM_ functions and don't use GM_log() at all.
All of Firebug's console functions work great from within a GM script.
Note: this answer refers to old versions of Firefox. Firebug is no longer available, but lives on in the Developer Edition of Firefox.
Current Firefox and Firebug can now debug current Greasemonkey scripts just like any other javascript. Just find your *.user.js script in the dropdown menu. The console also works.
This works at least on Firefox 28.0 and Firebug 1.12.7; I haven't tried earlier versions.
Note: In order to get it to work, you probably have to set extensions.firebug.filterSystemURLs to false. See "Profiling Greasemonkey scripts" in the Firebug, bug tracker. (Thanks to Shuman)
var e = document.createElement("script");
e.src = 'http://www.xxxxxxxx.com/yyyyyyyy.js';
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
you can add this to your xxx.user.js, and install it in greasemonkey.
Then, you can debug your js as you wish.
None of the other solutions here worked for me, but Jan Odvarko's answer on how to debug Firefox extensions worked perfectly for GreaseMonkey scripts as well:
On Firefox 19 or later, it's possible to use the built-in JS debugger
on the browser itself. Go to about:config and set the following two
prefs:
devtools.chrome.enabled: true
devtools.debugger.remote-enabled: true
After you restart the browser, you can access the Browser Debugger
through Tools > Web Developer > Browser Toolbox.
(note that you must accept the incoming connection)
See more at:
https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/Debugging_JavaScript#JavaScript_Debugger
Then just search for the name of your userscript and start debugging.
It can be done using native Firefox debugger as it was mentioned before. Below is the instruction for modern versions of Firefox.
Set the following preferences in about:config:
devtools.chrome.enabled: true
devtools.debugger.remote-enabled: true
devtools.debugger.prompt-connection: false
Open the global script debugger window via
Tools → Web Developer → Browser Toolbox → Debugger (or Ctrl+Shift+Alt+I) .
Search for the name of your userscript and start debugging.
-- This answer is obsolete, please use #Brock Adams solution above --
Load your main script externally, instead of running it via GM. So you're just using GM to inject the script.
This is a bit of a hybrid between #bigml and #Yuval's solution and it uses jquery. It also works in frames.
// ==UserScript==
// #name My GM script
// #include The website I want this to run on
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// ==/UserScript==
$(document).ready(function() {
// fetch jquery dependent scripts using $.getScript()
});
Note: ChromeBug no longer exists. The Developer Edition of Firefox is an alternative.
Chromebug can see sandboxed scripts, http://getfirebug.com/wiki/index.php/Chromebug_User_Guide, but I've not tried it on Greasemonkey.
Similar to #bigml's suggestion, you can run it unprivileged if you setup a local webserver (apache) to serve the userscript file, then in your userscript add something along the lines:
if (typeof GM_addStyle == "undefined") {
loadScript("http://localhost/path/to/script.user.js");
}
else {
runScript();
}
function loadScript(url) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.getElementsByTagName('head')[0].appendChild(res);
}
function runScript() {
// ... whatever your userscript does ...
}
Of course you wouldn't be running in a privileged context. But this way you can easily continuously debug the script as any other script.
Note: this answer refers to old versions of Firefox. Firebug is no longer available, but lives on in the Developer Edition of Firefox.
I've tried ChromeBug, it doesn't seem to work.
With FireBug I have had the starting point of success by adding "debugger" to my GM code. This causes a breakpoint and I can inspect variables on the stack, but the right file is not shown so I can't step or anything.
I have had the best success with FirebugMonkey (https://
addons.mozilla.org/en-US/firefox/addon/13623/), which I just got working to do basic
debugging of GreaseMonkey scripts thanks to some explanation in a
recent comment on the extension page by f0rsvinn. Here are the instructions I just posted at http://groups.google.com/group/greasemonkey-users/browse_thread/thread/994cfa58c79d222:
It never occurred to me that the way it works is by creating its own
sandbox around the script rather than using Greasemonkey's, you
actually have to turn GM off. There are some GM aspect things that
will not work though because the script really isn't in GreaseMonkey.
As an example, GM_getValue returns undefined.
Still, it works for basic debugging - and is way better than nothing.
Usage steps are as follows:
Install FireBug 1.5.4 (later versions do not seem to work)
Install FireBugMonkey
Use the Script Manager in FireBugMonkey to select the files you want to debug
Disable GreaseMonkey (scripts will run inside FireBugMonkey, not
GreaseMonkey)
Enable FireBugMonkey
Enable scripts in FireBug
The scripts you added in the ScriptManager should be visible in the
FireBug scripts list.
As the others have said, you can setup a simple HTTP server and serve it to your page using Greasemonkey like so:
function loadScript(url) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
WEBrick and Python -m SimpleHTTPServer are good for this. We can also expose the GM_... functions to the script by adding a custom event handler to the document within GreaseMonkey:
function gMHandler(e){
GM_log(e.detail.message);
e.detail.response = "Hi!"
}
document.addEventListener("gM", gMHandler, false);
and then in the served script, raising this event on an arbitrary DOM element will run the handler and modify the element's response parameter:
$(document).ready(function() {
var event = new CustomEvent(
"gM",
{
detail: { message: "Hello World!" }
bubbles: true,
cancelable: true,
}
);
document.getElementById("AnyElement").dispatchEvent(event);
alert("Response was: " + event.detail.response);
});