watir/ruby waiting for iframe to exist - ruby

I have a problem waiting for an iframe to exist on page after entering a date range and I would rather not use sleep. I am using ruby/watir
I have tried solutions like this -
wait_until(10, "iFrame has not loaded") do
#browser.iframe(id: "dtl00_DP1_content").exists?
end
but this simply returns this error - Selenium::WebDriver::Error::NoSuchWindowError: no such window
So how do I wait for an iframe that does not yet exist please?

I am not sure whether you only want to wait for an Iframe, If you want to perform any operation on an element which is present in the iframe, then you could do as I mentioned in my comment.
#browser.iframe(name: "something").text_field(name: "username").set 'raja'
Or If you still wait for an iframe to appear, then write the following code
#browser.wait_until { #browser.iframe(id: "dtl00_DP1_content").exists? }
The above code waits for 30 seconds, but If you want to increase the time to wait, then write the following code, the following code would wait fo 50 seconds.
#browser.wait_until(timeout: 50) { #browser.iframe(id: "dtl00_DP1_content").exists? }

Related

Last index can't be located

I have a very different problem here.
I have this code
xpath = "//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table"
array = #browser.table(xpath: xpath, visible: true).rows.map { |row| [row.cells[0], row.cells[0].text] }
col = array.filter_map { |x| x if x[1].eql?(result) }
When I am executing the aforementioned code, it throws the following error
timed out after 10 seconds, waiting for #<Watir::Row: located: false; {:xpath=>\"//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table\", :visible=>true, :tag_name=>\"table\"} --> {:index=>10}> to be located\""
10 is actually the last index of the table.
But it works fine if I put sleep 5 before my code segment. However, I was expecting WATIR to be automatically waited, but this is not the case, May I know why?
Here is more clear explanation
I am printing this line
p #browser.table(xpath: xpath, visible: true).rows.count
With sleep this is printing 10
without sleep, this is throwing the following error ends with {:index=>11}> to be located\, you could see the full error below
"timed out after 10 seconds, waiting for #<Watir::Row: located: false; {:xpath=>\"//div[#class='z-listheader-content'][normalize-space()='Name']/ancestor::table/../following-sibling::div/table\", :visible=>true, :tag_name=>\"table\"} --> {:index=>11}> to be located\""
Per the Documentation on waiting there are a few key points that should be noted:
The idea behind implicit waits is good, but there are two main issues with this form of implementation, so Watir does not recommend and does not provide direct access for setting them.
The wait happens during the locate instead of when trying to act on the element. This makes it impossible to immediately query the state of an element before it is there.
Implicit waits by themselves will not be sufficient to handle all of the synchronization issues in your code. The combination of delegating waiting responsibilities to the driver and leveraging polling in the code (explicit waits) can cause weirdness that is difficult to debug...
...The second and recommended approach to waiting in Selenium is to use explicit waits...
...Note that Watir does its automatic waiting when taking actions, not when attempting to locate...
In your case the wait is needed for location and thus the "automatic" wait you were expecting is not actually how watir works.
The Watir library does however provide mechanisms for explicit waits:
wait_until which waits until a specific condition is true
wait Waits until readyState of document is complete.
It appears that based on your posted issue that a waiting timeout has expired for your location before the element could be found.
It is possible that wait_until would resolve this e.g.
table = #browser.table(xpath: xpath).wait_until(&:visible?)
puts table.rows.count

cy.type stop mid-typing, finishes after .wait

I'm seeing an issue where cypress (v6.9.1) is randomly stopping mid-type, despite the fact that no other events are triggering on our page, and continuing after a .wait as it proceeds to execute other commands.
cy.get(`[placeholder="Search"]`)
.clear()
.click()
.type(search) //types a portion of 'search', then stops
.wait(500);
//continues typing the rest of search
This issue is sporadic and can not be reliable reproduced, and can and has happened on any text input on our app. Any ideas on what could be causing it?
You can add a delay while typing something like below. Now each keypress will be delayed 50ms.
cy.get('[placeholder="Search"]').clear().click().type(search, {delay: 50})
When using a component like React Async Select and wanna select an option you can do.
cy.get("#elementid").type("Jef{enter}", { delay: 100 });
so each consecutive keystroke, it will wait 100 ms. Not the greatest solution as it's arbitrary.
I haven't found a better solution using cy.intercept so if anyone has one, please let me know.

XMaskEvent not returning

I am following this tutorial here: http://www.sbin.org/doc/Xlib/chapt_16.html
Here is the image of the tutorial:
Here is my code: (it is in another thread from which I called XInitThreads - I know using threads and X is bad, I know I should be on the main thread, but just wondering if possible)
var ev = XEvent();
var rez_XMaskEvent = XMaskEvent(cachedXOpenDisplay(), ButtonPressMask | ButtonReleaseMask, ev.address());
console.log('rez_XMaskEvent:', rez_XMaskEvent);
console.log('ev:', ev);
ButtonPressMask is 4
ButtonReleaseMask is 8
So XMaskEvent is blocking, but whenever I press my mouse button it is not catching it. Shouldn't it unblock and get to the console.log line?
Do I need to run an event loop somehow in this thread?
Thanks
I'm not 100% sure here but I feel this could be your problem:
You probably can't do this from JavaScript without some extra precautions. JavaScript in the browser is single-threaded. That means you're holding a lock and no other JavaScript can run. Your problem is a) you're using threads and b) "If the event you requested is not in the queue, XMaskEvent flushes the output buffer and blocks until one is received." (see the man page)
That means XMaskEvent blocks since the button hasn't been pressed, yet. And your browser can't execute JavaScript anymore. If there is an event in the queue which would trigger some JavaScript, the browser will lock up.

Stop loading page watir-webdriver

Is there a way to stop loading a page with watir-webdriver on firefox? Or is there a way to force something in my script even if the page is still loading? At a point in my script, the website will hang and the script eventually timeouts.
You can use the Timeout class to force it to give up after waiting a reasonable amount of time (and this is internally how Watir performs it's waits as well)
begin
Timeout::timeout(10) do
# perform actions that may hang here
end
rescue Timeout::Error => msg
put "Recovered from Timeout"
end
If the website hangs, you should be able to use a wait method to timeout the script if an element does not appear. These are mainly used as an answer to AJAX, but they should work for this condition as well. For example, if the script hangs after you click a link, and you expect the next page to have a specific title or text:
#browser.link(:name => "Let's Hang!").click
Watir::Wait.until(30) { #browser.title == "new page" }
or
Watir::Wait.until(30) { #browser.text.include? ("confirmation text") }
or
#browser.image(:src => "awesome.jpg").wait_until_present(30)
Each of these will wait 30 seconds for the condition to be met before exiting with an error. You can change the time (30) to exit within your app's hang window.
please have a look at the Selenium issue http://code.google.com/p/selenium/issues/detail?id=687 it's not fixed yet, watir-webdriver is also based on Selenium, hope it answers your question.

Dialog not available within 60 seconds

I am trying to use Dialog handler twice in a function. For first time it executes well but on second time it hangs the system with dialog box open and showing Ok and Cancel butoon but never able to click it. Also it times out with an error "Dialog not available within 60 seconds"
Dim cdhPopup As ConfirmDialogHandler
cdhPopup = New ConfirmDialogHandler()
If (ie.Button(Find.ById("btnDelete")).Exists) Then
'Cancel the booking '
ie.AddDialogHandler(cdhPopup)
ie.Button(Find.ById("btnDelete")).ClickNoWait()
cdhPopup.WaitUntilExists()
cdhPopup.OKButton.Click()
ie.WaitForComplete() 'Wait for page to finish loading '
Else
Assert.Fail("Could not found the Cancel Button")
End If
Using this at 2 places in my code, First time it executes fine and second time within same function it gives dialog not available whereas it is available error.
My best guess is that in the second pass you are again calling
ie.AddDialogHandler(cdhPopup), thereby registering it a second time, which is somehow crashing the program when the handlers are invoked (cross thread access to internal variables maybe?)
You should perform a check if the handler is registered, and only register it if it isn't.

Resources