Capybara drag_to dragging to mouse location instead of target - ruby-on-rails

I'm trying to write a test that involves dragging and dropping (via SortableJS) to order some things on a table.
Here's basically what's in my test currently:
handle = find("[data-item-id='#{itemA.id}'] [data-js-sortable-handle]")
targetRow = find("[data-item-id='#{itemB.id}']")
handle.drag_to(targetRow)
This sort of works, except that rather than dragging to targetRow it drags to where my mouse actually is. So my test only passes if I put my mouse in the right location, and if I don't run them headless.
I'm unsure if this is more of a problem with Capybara, Selenium, or just because of the library I'm using.

Depending on exactly which type of drag and drop (JS emulated vs HTML5) the sortablejs library is using Capybara has to do different things. I don't really see how either of the methods it uses could drag to the wrong element (where the drop/mouse_up event occurs) but it's definitely possible the positions reported in the events may be off if your app depends on those positions. There are tests for both types of dragging in the Capybara test suite which do pass in headless and headed modes, so it definitely should work in at least basic cases. If you can provide a simple example that shows your issue, please file an issue at the Capybara project with the example and I'll take a look.
UPDATE: I took a look at the SortableJS code and found at least one reason why Capybaras HTML5 DND emulation isn't compatible with it. SortableJS handles the dragstart event by running some setup code via setTimeout. Since Capybaras code was all in one script the SortableJS dragstart setup code wouldn't get executed until after the drop event occurred which prevented elements from getting moved. I've made some changes to Capybara and released 3.23.0 which should play nicer with SortableJS.

Related

"Cached element do not exists in DOM" when run Appium with Robot Framework

I'm working on automated test using Appium with Robot framework on Android device. I create schedule run on Jenkins. My test flow is entering some data in page A and submit, then switch to page B to check the result and switch to page A to enter a new data. I repeat this loop for around 10+ time. Everything works fine in around 4-5 rounds but after that there show up an error :
StaleElementReferenceException: Message: Cached element 'By.xpath:
//android.widget.TextView[#text='Limit']' do not exists in DOM anymore
The TextView is in the page A. I monitored the robot and saw that the TextView was shown up but the robot did not see it. I tried restart the device but the problem is not solved. I search through the internet and found some who facing the same issue but they use different programming language like Java or Python. I have no idea what I have to do next.
Development Tools :
Appium version: 1.21.0
Robot Framework version: 4.1.2 (Python 3.10.0 on win32)
First I do not use Robot Framework, but the code should be similar according to this https://robocorp.com/docs/languages-and-frameworks/robot-framework/try-except-finally-exception-catching-and-handling.
Second, I'm not sure if this is the best way to get around this. I think there is something you can do with the expected conditions class to get around this in a "cleaner way" but I'm not quite familiar with it enough to show/tell you. Instead what I've done is something like this...
from selenium.common.exceptions import StaleElementReferenceException
while some_limiting_factor:
try:
# logic for submitting page A, assertions for page B
except StaleElementReferenceException:
element = driver.find_element('By.xpath: //android.widget.TextView[#text='Limit']' )
As much as I want to cache elements in appium, it seems that the service itself does NOT want you to, at least not in my experience. Getting a fresh element(s) every time seems to ensure a "slow but steady" test. Hopefully someone can show me the deep appium secrets one day.

Cucumber test fails on unscrollable page

Here is a test (I've opened the inspector during the test and that's definitely the element hierarchy):
within('table.foo') do
find("tr#foo_#{ #foo.id }").click
end
Calling find() on the element returns:
could not be scrolled into view (Selenium::WebDriver::Error::WebDriverError)
I have a pretty good idea why--the page renders a single db entry created for the purpose of the test, and so the document doesn't extend past the window, making it unscrollable, which I think is what's throwing this error.
I have tried updating geckodriver to no avail.
Is there a method in cucumber that doesn't prompt scrolling? Would be better than a) testing in a really tiny window or b) creating more test data just to stretch the document.
This sounds like a bug that exists in an older version of chromedriver that is caused with newer/later versions of Chrome. The bug is the driver would lose the ability to scroll the tab in focus.
I would recommend downloading the latest driver and replacing the one you are using.
https://sites.google.com/a/chromium.org/chromedriver/downloads
Cheers.

Can I use gBrowser.selectedBrowser.addProgressLisnter in e10s?

We're trying to migrate our add-on to message manager and frame scripts.
Previously our add-on used gBrowser.addProgressListener() and nsIWebProgressListener.onStateChange() along with browser.webProgress.isLoadingDocument to monitor network activity.
The question is can I continue using browser.addProgressListener and browser.webProgres.isLoadingDocument in future versions of Firefox or using webProgress from frame script is a better way to do that? Maybe I should use some other technique?
For some reason it doesn't work reliably in Firefox 36.0a1 so I thought I should maybe move the code to frame script. Namely frame's docShell is QI-ed to webProgress to add progress listener there. It also doesn't work in all cases so I guess it's just a bug in 36.0a1.
By "doesn't work reliably" I mean that onStateChange() isn't called when I try navigating by browser.loadURI() method when a blank page is loaded in the current tab. Also webProgress from frame script sometimes "forgets" to send STATE_STOP to onStateChange().

Selenium Web Driver Error

I'm getting a weird error while trying to click on a Capybara Element
I'm using find(:xpath,"//a[contains(text(),'Connect')]").click
(find(:xpath,"//a[contains(text(),'Connect')]").present? return true)
the error I get is:
Selenium::WebDriver::Error::MoveTargetOutOfBoundsError Exception: Element cannot be scrolled into view:javascript:void(0);
i did some research and the only solution i found is that setting the selenium version to 2.16 may fix this issue (i'm using 2.25).
anybody got an idea?
It may happen when the page being tested is not fit into the current window size. If you know such pages where usually these error happening, you may explicitly scroll down before doing the operation on such hidden elements(like click, clear etc). Here the code to explicitly scroll down the page.
In java,
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");
From the times I used selenium webdriver to test .NET apps, I would get that error when the issue was exactly what it sounds like: It's looking for an object on the page that it cant scroll to for some reason. In my case it was because some dialogue boxes would appear without scrollbars and the driver had no way to "scroll the object into view"
Can you watch the execution of your test and see if that's the case? I had some luck rolling back to a previous version of firefox because 15+ was (as of about 2 months ago when I had the issue) unsupported by web driver and had this problem periodically. Rolling back selenium versions may help too.
First step though is definitely to watch the execution of the test and see whats happening though. And a good debugging idea may be to try to work through your steps manually yourself to make sure the test works by hand.
Its also worth noting that for the webdriver to be able to execute click the object actually has to be visible. IsPresent doesnt require that, it just searches the page files. Also an issue I ran into. IsPresent will still return true for objects that are not and cannot be made visible on the page (i.e. something at the bottom of the page that you cant see at the time)
Couple of tips here:
Webdriver should ideally be on the most recent update, it's what most use (Unless you're doing Ruby Automation)
Use css selectors, xpath (Whilst rendered), is almost always heavier on both resources and code.
Try defensive coding, first of all ascertain it exists. There are many ways to do that dependent on what package you are using. In ruby you would do page.has_css?('css_string')

How to disable TAction.Shortcut or TMenuItem.Shortcut?

I'm developing a Word addin, and somehow the shortcuts defined in TAction.ShortCut are always trigged more than one time, and this is tricky to me and hard to solve, so I resort to TForm.OnKeyDown event and cleared all TAction.ShortCut properties, this approach works well, except that the shortcuts are not shown on the corresponding menu items, but I want them to be displayed on those menu items.
So I come up this idea: Set values for TMenuItem.Shortcut so that the program can show the shortcut hint to the end user, and does not allow VCL to handle these shortcuts, instead, handle them in TForm.OnKeyDown. So my question is how to disable TAction.Shortcut or TMenuItem.Shortcut? Thank you in advance.
For a start, you have an Enabled property on both TAction and TMenuItem. Just set it to False.
Next, one of the possible causes of your event being triggered more than once is that you may be using Application.ProcessMessages; or at least a badly written component that you're using is doing so. One should be very wary of using that Delphi feature because it can cause 're-entrant' code (unintentional recursion).
The root cause of your problem is the events being triggered more than one time. You could try to workaround this problem offcourse but I would suggest to:
Place a breakpoint in your eventhandler.
Copy the Call Stack's content [CTRL+ALT+S] to whatever editor you like for every time you hit the breakpoint.
Start brainstorming as to why the calls lead to hitting the event multiple times.
Fix your code if it is your code to fix.
Hacker way (usually not recommended):
copy unit that contain TAction in separate folder, modify source of TAction that makes ShortCut method do nothing. Put this folder to search path as first item.
rebuild your app.
I use this technique to fix bugs in VCL, but after installing Delphi patches you should not forget to update 'hacked' version of modified units.

Resources