I am buidling a test script for a webpage which posts data to some application and shows the result back. The problem is that the script does not load the data from the javascript modal popup. I would like to state here that it is not an alert it is a simple javascript popup.
The popup has a link in it like
Google
The script click a link and then the popup appears but it can not read the link from the popup. With a lot of testing I have came to the conclusion that the script runs through the page before the popup appears. This is the reason that it does not read the popup link. Follow code is being used to read popup.
#driver.find_element(:css, "a.popup-link").attribute("href")
I have also tried both implicit and explicit waits but still the problem persists. I have set the implicit wait to 30 seconds by using
#driver.manage.timeouts.implicit_wait = 30
The explicit wait like this
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until { driver.find_element(:css => "a.popup-link") }
element = #driver.find_element(:css, "a.popup-link")
What should i do so that i can read the popup link properly? Any suggestions?
Related
Until recently, I was using mechanize to get a web page, then do some parsing with nokogiri. But because some content was loaded with Ajax after I have started using Watir instead. My code looks like this:
def get_page(url)
browser = Watir::Browser.start url
sleep 1
page = Nokogiri::HTML.parse(browser.html)
browser.close
return page
end
It works fine but since I am getting a lot of pages the browser.start will open a tons of windows. I found the close as you see, but is there a way to just not show the browser window at all?
Following is the code i am using
def self.yes_publish
sleep 5
driver.find_element(:id, 'dialogConfirmChanges-publishButton').displayed?
WAIT.until { driver.find_element(:id, 'dialogConfirmChanges-publishButton') }.click
puts driver.find_element(:id, 'embed-left-center-part').displayed?
end
But i am unable to click on it. This id works fine in irb.
I get an error modal dialog present, as webdriver is unable to locate element it closes to window after a particular timeout.
This popup is to publish changes made on a page.
xpath = .//*[#id='dialogConfirmChanges-publishButton']
You have to use the switch_to method to deal with the pop-up. Look at the documentation of JavaScript dialogs :
You can use webdriver to handle Javascript alert(), prompt() and confirm() dialogs. The API for all three is the same.
Note: At this time alert handling is only available in Firefox and IE (or in those browsers through the remote server), and only alerts that are generated post onload can be captured.
require "selenium-webdriver"
driver = Selenium::WebDriver.for :firefox
driver.navigate.to "http://mysite.com/page_with_alert.html"
driver.find_element(:name, 'element_with_alert_javascript').click
a = driver.switch_to.alert
if a.text == 'A value you are looking for'
a.dismiss
else
a.accept
end
EDIT
As per the comment box HTML given by you..I think below should work :
driver.find_element(:xpath,"//div[#class='ui-dialog-buttonset']/button[#id='dialogConfirmChanges-publishButton']").click
on my web application, after clicking a download button, a popup message with content "Do you want to open or save "abc.txt" from this site?" with 3 buttons ("Open", "Save" & "Cancel") will be displayed at the bottom of page.
I'm trying to close/quit this browser session with below codes:
#driver.execute_script "window.onbeforeunload = function(e){};"
#driver.quit
However, the browser is NOT (but should be) closed. I'm working with Selenium Ruby Webdriver. Please guide me a way to resolve this problem. Thanks so much.
Note that with the above codes, I'm able to close IE9 browser that has the popup message "This page is asking you to confirm that you want to leave - data you have entered many not be saved" with "Leave Page" and "Stay on Page" buttons successfully. But, codes do NOT work in case the popup message with content "Do you want to open or save "abc.txt" from this site?" with 3 buttons ("Open", "Save" & "Cancel") displayed.
WebDriver has no control over these types of "Save file" dialog prompts.
Please peruse this article on this subject (note, his examples are in Java, but they can all be ported easily and with less code in Ruby). http://ardesco.lazerycode.com/index.php/2012/07/how-to-download-files-with-selenium-and-why-you-shouldnt/
Thus, I would recommend not even clicking the link in question and trying to deal with the dialog. Instead, grab the href value and initiate a Net::HTTP request to it like this SO response shows you how to do: https://stackoverflow.com/a/4581116/1221475 . You can then check the file for correct contents and such using standard Ruby and file parsers.
This is a hack by Dave Haefner. It is written for Java/Selenium combination, but you can easily convert it to Ruby syntax.
If you don't care if a file was downloaded or not and you want to confirm only that a file can be downloaded, you can use an HTTP request. Instead of downloading the file you'll receive the header information for the file which contains things like the content type and length. With this information, you can confirm the file is you expect.
String link = driver.findElement(By.cssSelector("download-link-element")).getAttribute("href");
HttpClient httpClient = HttpClientBuilder.create().build();
HttpHead request = new HttpHead(link);
HttpResponse response = httpClient.execute(request);
String contentType = response.getFirstHeader("Content-Type").getValue();
int contentLength = Integer.parseInt(response.getFirstHeader("Content-Length").getValue());
assertThat(contentType, is("application/octet-stream"));
assertThat(contentLength, is(not(0)));
I have a script that visits fcc.gov, then clicks a link which triggers a download:
require "mechanize"
docket_number = "12-268" #"96-128"
url = "http://apps.fcc.gov/ecfs/comment_search/execute?proceeding=#{docket_number}"
agent = Mechanize.new
agent.pluggable_parser.default = Mechanize::DirectorySaver.save_to 'downloads'
agent.get(url) do |page|
link = page.link_with(:text => "Export to Excel file")
xls = agent.click(link)
end
This works fine when docket_number is "12-268". But when you change it to "96-128", Mechanize downloads the html of the page instead of the desired spreadsheet.
The urls for both pages are:
http://apps.fcc.gov/ecfs/comment_search/execute?proceeding=12-268 (works)
http://apps.fcc.gov/ecfs/comment_search/execute?proceeding=96-128 (this is where I need help)
As you can see, if you visit each page in a browser (I'm using Chrome) and click "Export to Excel file", a spreadsheet file is downloaded and there is not problem. "96-128" has many more rows, so when you click on the Export link, it takes you to a new page that refreshes every 10 seconds or so until the file begins downloading. How can I get around this and why is there this inconsistency?
Clicking Export on 96-128 takes you to a page that refreshes using this kind of a tag (I've never heard of it before):
<meta http-equiv="refresh" content="5;url=/ecfs/comment_search/export?exportType=xls"/>
By default, Mechanize will not follow these refreshes. To get around that, change a setting on agent:
agent.follow_meta_refresh = true
Source: https://stackoverflow.com/a/2166480/94154
The proceeding 12-268 has 48 entries, 96-128 has 4046.
When I click at 'Export to Excel File' on the latter, there sometimes is a page saying:
Finished processing 933 of 4046 records.
Click if this page does not reload automatically.
I guess mechanize is seeing this, too.
I am using Watir with Chromedriver to automate form submission on some website. I have to login and submit multiple forms. The problem is, when I click the submit button the page the page automatically closes, so when I goto('next_url') I get this error:
/Users/jackz/.rvm/gems/ruby-1.9.3-p327/gems/selenium-webdriver-2.27.2/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok': 'auto_id' does not refer to an open tab (Selenium::WebDriver::Error::UnknownError)
The Watir instance is still there, but the window is closed. I could create a new instance every time, but then I would have to login again every time and this would take longer.
So how can I either:
Open a new window in the same Watir instance
or
Suppress the window from closing after I submit
require 'watir-webdriver'
#b = Watir::Browser.new :chrome
#b.goto(URL)
#b.buttons.first.click
#this is when the window closes
#b.goto(NEW_URL)
#then I get an error
Thanks
I figured out an answer to my own question. I can open a new window in Watir using javascript:
b = Watir::Browser.new
b.execute_script("window.open()")
b.windows.last.use
This opens a window where I can fill out the form, then when the window automatically closes I still have the original window to work with. Probably not the best solution, but it works for now.
Add this to your existing code if your using chrome. else, modify accordingly as per your browser.
This will keep the window open, and the current watir session active.
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => false})
browser = Watir::Browser.new :chrome
What Mrityunjeyan suggested above was in a right direction, but you need to change a few things to make it work.
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => true })
b = Watir::Browser.new('chrome', desired_capabilities: caps)
Check the documentation here.
https://sites.google.com/a/chromium.org/chromedriver/capabilities