Ruby/Watir getting stuck after using "goto" - ruby

I'm using a simple browser.goto(url) call to our Microsoft SQL Reporting pages. It does a "goto" on the first url but then just sits there. I'm currently running it via command line.
If I Ctrl+C to cancel it, the output says:
C:/Ruby/lib/ruby/gems/1.8/gems/watir-1.6.5/lib/watir/ie-class.rb:506:in `wait': Interrupt
from C:/Ruby/lib/ruby/gems/1.8/gems/watir-1.6.5/lib/watir/ie-class.rb:355:in `goto'
from screen.rb:37:in `SqlReports'
from screen.rb:35:in `each'
from screen.rb:35:in `SqlReports'
from screen.rb:45
So, I'm guessing something on the page is causing Waitr problems. I've googled the about snippets, but not come back with anything. All I want it to do is load the page, sit there for a specified time, then move to the next url (it's for a tv screen), nothing complex.
So I've tried placing a "begin/rescue" ie:
begin
$browser.goto(url)
rescue
end
No luck, it just sits on the first url. And I've tried wrapping that using the Timeout class, ie:
begin
Timeout::timeout(30) do
$browser.goto(url)
end
rescue
end
Still no luck, it crashes out. Does anyone know a fix, or how to override the implicit "wait" that Watir does when doing a goto?

My guess would be that there is something on that page that keeps IE from saying "I'm done loading everything here".
There is a $browser.click_no_wait command and a $browser.click! command, so if you had a static page that had a link to your url, you could $browser.goto that page and clcik_no_wait the link.

an excellent solution using timeouts at http://watirboy.blogspot.com/2010/07/watir-timeout-handle-browser-hangstuck.html

Related

Select() method and option() method works differently

Today I have seen a question in selenium C# section where this question was posted, I try to solve that problem through WATIR coding, I have written the below code and WATIR identifies this select list as invisible.
b.goto 'http://automationpractice.com/index.php'
b.img(title: 'Faded Short Sleeve T-shirts').click
b.iframe(xpath: "//*[starts-with(#id,'fancybox-frame')]").select_list.select("L")
But If I select that same select_list through below metioned code, it works fine.
b.iframe(xpath: "//*[starts-with(#id,'fancybox-frame')]").select_list.option(text: "L").click
I don't understand what is the difference here, when I put a debug pointer, both are making a selenium call to find_element(tag_name: "select"), first one fails due to element invisible but second one passes
#Titus, #JustinKo Can you please explain me what's happening here? what's the difference?
Note: Please run it in Chrome.
Moving from a comment to an answer:
The issue is that we refactored the normal (non-select-list) way of doing it to not check for whether an element is displayed ahead of time, and put the waiting logic in the rescue block if Selenium complained. The select-list code is still checking the visibility ahead of time, and this particular select-list element is not displayed according to Selenium. Since it appears that Selenium can select options without select list showing as displayed, Watir should not be waiting for this.
I've fixed it here, and it will be working in Watir 6.13 (should be released "soon")
https://github.com/watir/watir/commit/77af164fcdecb71d8d2240110d3fb4b1dabeee4b

Watir: Trouble with if statements

I spent a while looking but didn't find anything that helped much, so I decided to ask myself.
Anyways, I'm trying to make a non-malicious bot to respond to certain forum threads on a forum. However, I'm stuck on making an if statement that will detect if a thread has a certain name, and click on that thread if it does. This is what the closest I've come:
def Replies()
while true
$browser.div(:text => ':HexBot/Summon')
sleep(5)
$browser.goto <insert link here. i didn't include it for privacy reasons>
end
end
What this should do is refresh the page every 5 seconds. If it sees a thread saying ':HexBot/Summon' then it would click on that thread. However. I just get an error. I tried doing this entirely without if statements, but that also gave me an error.
I'm not completely sure I understand the question, so let me know if this isn't what you are asking for:
def Replies()
until $browser.div(:text => ':HexBot/Summon').present?
sleep(5)
$browser.goto <insert link here>
end
$browser.div(:text => ':HexBot/Summon').click
end
That should reload the page every 5 seconds (forever) until the desired text appears, at which point the text will be clicked. You could also use $browser.refresh instead of the $browser.goto statement (assuming you start on the correct page).
Lastly, you tagged this question watir. I use watir-webdriver, and there are some differences, but hopefully what I have offered here works for you.

Copying files from one directory to another is not working in Ruby

I am using fastlane and snapshot to create screenshots automatically. To facilitate this I need to copy data into the app. In this case a series of folders and documents from one folder into another within a .app container.
So far the Documents folder is being created but no files are ever copied into it. At this point I’m not sure if I’m suppling the path incorrectly or what else I might be doing wrong to lead to this. It may be simply that I’ve got the wrong code to do that since I’m not that familiar with Ruby.
Any suggestions would be greatly appreciated, so tell me, what am I missing?
example_files = "./sample_data/Documents"
folder_name = "Documents"
setup_for_device_change do |lang, device|
app_path = "/tmp/snapshot/build/SyncSpace.app/"
FileUtils.mkdir_p(File.join(app_path, folder_name))
Dir.glob(File.join(example_files, '*')).each do |example_path|
FileUtils.cp_r(example_path, File.join(app_path, folder_name)) rescue nil # in case the file already exists
end
end
Update -
In the end my problem is that the path I’m using doesn’t work correctly for the files I want to transfer. When I give it a full path from the root level to the folder I need it works. Trying to use a shorter path with just the additional folders over the working directory fails.
So as a follow up, when my working directory is .../fastlane and my data is in .../fastlane/sample_data/Documents then why doesn’t just using ./sample_data/Documents work?
Don't use rescue nil. Ever, or at least until you're very aware of what your code could be doing and why you would want to use that. Instead use the normal form of:
begin
do_something
rescue TheExactExceptionYouWantToHandle => e
# handle the exception
end
That way you handle what you expect and blow up if it's something you didn't expect.
One of my programming mentors years ago told me
Never test for an error condition you don't know how to handle.
On the surface that sounds silly but experience teaches us we can get into situations where the program does the wrong thing trying to do the right thing. It's better to crash fast and safely and spew out an error, than to drag it out and damage things trying to recover or silently cover the error. Debugging a program that's rescuing improperly can be a major pain and a trailing rescue is a common culprit.

slow typing due to Sys.Desktop.KeyDown and Sys.Desktop.KeyUp methods

We are using Sys.Desktop.KeyDown and Sys.Desktop.KeyUp VB methods of TestComplete to type into Notepad.
For this we are using a for loop containing KeyDown and KeyUp, however for some reason, even after the for loop ends, the typing is still not complete, its typing slowly, not sure why.
I checked by removing anti-virus software, but still seeing the issue. I have also tried to use the Win32API.GetKeyState(Asc("A")) however sometimes we get 1 and sometimes 0, so really need to debug this issue out. Could anybody suggest a way to debug this issue?
Are you able to use .Keys() on the main text area object?
Something like:
Set textObject = Sys.Process("notepad").Window("Notepad", "Untitled - Notepad", 1).Window("Edit", "", 1)
Call textObject.Keys("Hello")
This is my preferred way of sending text when it is directed toward a particular object. Please refer to this link for more information on the Keys method.

Trouble with greasemonkey script to refresh page

I'm downloading data from an online database using the imacros plugin for firefox. It works perfectly, except when the page times out. I've moved to downloading very small chunks of data since then the website times out much less frequently, but it still times out occasionally.
The problem is there's no way to code if statements directly into the imacros macro, so I wanted to have a greasemonkey script running along side it that will refresh the page if it timesout. The website only times out in one place for me, and when it does it shows the following:
can't open file
I never learned Java or Javascript and all of my programming experience deals with numerical methods, but I've been been piecing together code and adapting it to try and solve my problem.
The following is my base code:
var RefreshTime = '20';
var str1 = document.body.innerHTML
var str2 = "can't open file"
if (str1.search(str2) > 0) {
if (StRefTime > 0) setTimeout("location.reload(true);",RefreshTime*1000);
}
Since the browser I'm running this in is currently being used exclusively for this script I just have #include *
Basically what this is meant to do is refresh the page every 20 seconds as long "can't open file" is found the webpage. This works perfectly on other websites when I test it, but doesn't work at all on the website I need it to. It might be worth noting that when I refresh, firefox asks me to confirm resending post data - but imacros does have a function that I tested and works on this site to automatically confirm whenever the dialog is displayed.
After doing some reading I found that other people had similar problems, and I think the root of the cause is that if the page is arrived at through AJAX then greasemonkey misses it.
To address this I tried to implement the suggested solutions to those people, but I've been unsuccessful. For example I've tried putting the code I listed above into the solution given here: Run Greasemonkey script on the same page, multiple times? , for example
var RefreshTime = '20';
var str1 = document.body.innerHTML
var str2 = "can't open file"
function highlightGoodComments (jNode) {
//***** YOUR CODE HERE *****
if (/str2/i.test (jNode.text () ) ) {
if (str1.search(str2) > 0) {
if (RefreshTime > 0) setTimeout("location.reload(true);",RefreshTime*1000);
}
}
But this doesn't work either, and I've tried a couple variations of it (for example getting rid of str2 and just putting "open file" and things like that) and I've also tried and failed to make the following work https://gist.github.com/BrockA/2625891. I also tried wrapping all of my initial code in a setInterval loop with the hope that it would just check constantly for "can't open file" even without any page loading, but that didn't work either.
Unfortunately the website I'm running my script on is hidden behind a paywall, and it's hard to test my code since it times out somewhat randomly so there's no way to check if my code works outside of just waiting a long time and seeing if it failed. I know nothing about AJAX, so I'm not sure how to confirm that that is what's happening, but I still believe it to be so since my problem seemed similar to other people's - and when I enable this macro it does seem to interfere with other parts of the website but not the parts that my script works on.
I was hoping somebody could help me out, since I'm pretty stuck here and already in over my head. Even if you can't help, having some sort of AJAX website where I could test code without waiting several hours would be helpful to me trying to figure this out myself, if anybody knows of one. Thank you for reading through this, I really do appreciate any help anybody can offer.
The question is very long so I didn't bother to really read it. Since I don't use GreasMonkey I can tell you the iMacros solution.
Check if html element exists with iMacros and javascript
Here is a model how to built JS iMacros script and include if clause. You can make a testing macro that tests is t here "can't open" web page.
Also you can try to use
SET !TIMEOUT_PAGE 120
command to increase the time of page loading to 120 seconds. Try some of these if it can help.

Resources