I have an application, and it works such way: when I tap & hold some element, context menu is shown, then I can move my finger to specified element and release it on appropriate menu item. I try implement this logic with Appium, but it's failed.
At first, I tried press element, then move_to another:
Appium::TouchAction.new.press(element: my_elem).perform
Appium::TouchAction.new.move_to(element: text(...)).perform
But before second action "finger releases screen" and context menu disappeared. Then I tried another way:
Appium::TouchAction.new
.press(element: my_elem)
.move_to(element: text(...))
.perform
But it fails with Selenium::WebDriver::Error::NoSuchElementError: No element found, because element, where we move_to, didn't appeared yet.
So, tell me please, how can I implement neccessary logic?
Not sure about Ruby but in java first you release() it before perform(). Also, if this doesn't work, look if duration() method is availabe in Ruby. Then you should use somethings like:
element.longPress.duration.release.perform();
In case if you don't find duration method, then its a bug in Appium what they are working on. Look at this:
https://github.com/appium/appium/issues/4695
Try this:
driver.scrollTo("string").tap(1,2000);
First, make sure that the element you want move to is really reachable. If it is but it hasn't appeared before you called the method then you should wait till the element appears. This is a sample in java
WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
This may look a little different in your case, but the idea is the same. After it passes, then call move_to, if it fails then probably your element is not reachable.
If the problem is like you said,
But it fails with Selenium::WebDriver::Error::NoSuchElementError: No element found, because element, where we move_to, didn't appeared yet.
Then try this
wait = Selenium::WebDriver::Wait.new :timeout => 10
then you can do something like this
wait.until { moveTo(element: text(...)) } ...
You probably have to adapt this to your case, I just wanted to show you the idea, you can read more about this here
Related
I am writing UITest cases for my Xamarin forms project. Now, i am stuck at Navigation Part. I know using "app.Back()" we can navigate back but on our Project Hardware Back Button is disabled. Is there any way we can use Navigation Bar "Back button" ?
I tried to get elements in Page by using following code "AppResult[] results = app.Query();" but still i am not able to find any element which says barbackbutton or backbutton etc in the list.
Bharat, after reading this a couple times, I think what you are asking is "how do I find the automation ids / elements to target".
There's a couple different ways to do this. My preferred one is App.Repl(). Here's the Microsoft docs on it, but in short:
at the point in your test where you are on the application view that you want to find an element on, put in App.Repl()
[Test]
public void CanTapButton()
{
App.Repl();
}
Run the test. When the test gets to this point, a repl window will open and the test will pause. End the test if you want, but keep the command window. It will look like this:
Type into the command prompt tree, to see the full layout of the page visible on the device.
You can use the app query calls in the Repl window to draft queries. For example,
app.Query(x => x.Marked("cpgTitle"));
will return the cpgTitle element that you can see listed in the tree. You can then use that app query to interact with the element, using something like App.Tap(appQueryVariable).
AppQueries docs are here and overall, it's very similar to selenium-style selectors.
Im using Nightwatch for e2e and Im finding these two command a little bit confusing given the name and explanation that comes with them.
.waitForElementVisible:
Waits a given time in milliseconds for an element to be visible in the page before performing any other commands or assertions.
What is the meaning of visible?
An element position in the footer, you need to scroll to see it, is it considered visible?
Does it mean visible in the DOM even if it is display:hidden, position:relative; left:20000px;, ...? Not actually visible for a user but dom is existing basically.
What is a modal view in on top of some content? Is it visible?
.waitForElementPresent:
Waits a given time in milliseconds for an element to be present in the page before performing any other commands or assertions.
What is the meaning of present?
Existing in the DOM without taking into account if it's visible or not?
Is there any relation/implication between these two command?
If an element return truth for .waitForElementVisible does it imply that .waitForElementPresent will return true?
A lot of questions but maybe an explanation about how they work would solve all of these small questions...
Sometimes Im just getting errors and Im thinking that it might be my bad understanding of these two commands.
What is problem with definition ? You already answer your question.
An element position in the footer, you need to scroll to see it, is it considered visible?
No,you dont need to scroll to check it visible or not.May be you do need with some command but not with these visible/present commands.
Does it mean visible in the DOM even if it is display:hidden, position:relative; left:20000px;, ...? Not actually visible for a user but dom is existing basically.
Yes,it exists(means present) in the DOM but for some reason it is not visible yet
(bad connection,attribute value,...).
If an element return truth for .waitForElementVisible does it imply
that .waitForElementPresent will return true?
yes it will, if an element is visible = > it is present.
For usage , you can check out my an example answer here,it might help .
Login timeout
Basically an element might be present (as in loaded in DOM) but not visible (e.g. out of view so you might need to scroll to see it, or it might be hidden).
If you want to perform an action like a click on an element then you want to be using 'visible'.
I need to implement a behavior:
when element clicked - one thing happens
but when it's clicked and held for more than one second, something else happens (e.g element becomes draggable) and then the first event never fires
I think I know how to catch click&hold type of events, but how to distinguish between first and second?
Can you show me how to do that using this jsbin. I already made the "click, hold & drag" part, except that it is still firing the 'click' event after dragging the element and it shouldn't.
again: element clicked - one event, click and hold - element is draggable (even after mouse up) and when clicked again it's back to normal (undraggable) state.
I am not looking for a trivial solution, it has to be built using Rx.Observable or at least Bacon's streamEvent object
Thank you
I think you were pretty close with your solution, but probably it is not possible to elegantly achieve what you want while using the browser's built-in click event.
HERE is my attempt to tackle your problem.
The main idea is to define your own click streams like so:
var clicks = downs.flatMapLatest(function(){
return ups.takeUntil(Rx.Observable.timer(250));
});
var longDownsStart = downs.flatMapLatest(function(){
return Rx.Observable.timer(1000).takeUntil(ups);
});
In case of clicks we wait max 250 ms after a mouse down for a mouse-up; in case of the latter we generate the event only if there was no mouse-up within 1000 ms.
There might be some corner cases in which the code does not work as intended.
Here is my proposed solution (with Bacon.js).
Say I have some code in production. I want to test that a particular item in a large list of items has some behavior. One way to accomplish this in development with the debugger statement is like this:
items.forEach(function(item){
// some code...
if (item.title.match(/foo/)) {
debugger;
}
// some more code...
});
With that code, you put a breakpoint in a list, only when the list item matches some expression. This makes it easy to debug only that one item, which may have some obscure bug in it. If you just try to put a breakpoint there by clicking the line, then it's going to pause at every item in the list, so you have to step through like 100 items before you get there which is super tedious.
One problem with the above is, it requires you to have the ability to edit the client-side JavaScript, which you can't really do in production.
So the question is, can you accomplish this same sort of thing, but purely using the Chrome Web Inspector? Maybe something to do with "watch expressions" (haven't found much on google about those). The ideal would be, from within the Chrome Web Inspector, add an expression like:
breakpoint:
line: 17
file: build.js
expression: item.title.match(/foo/)
The closest you will get to this without getting into Chrome's chrome.debugger APIs are conditional breakpoints.
If you truly want to do this programmatically, look into chrome.debugger.sendCommand with the Debugger.setBreakpoint command.
I am using Selenium Webdriver(Ruby) to automate my web app and my web app has this carousel wherein my element continuously keeps moving in a loop.
By the time I locate that element and try to click it, element moves ahead.Hence I am not able to locate that element.
I tried finding and clicking that moving element by following code:
{
ele_button = driver.find_element(:xpath,"xpath")
sleep 10
ele_button.click
}
I thought that by 'sleep 10' I could make that element wait for 10 seconds and then click it.But this does not work and I am getting ElementNotVisibleError whenever I run my script.
Question:
Is it even possible to automate a moving element? If yes please provide me a solution.
Yes it is absolutely possible. I handled same scenario for carousel on my site. There are three ways:
Most carousel stop on mouse hover. So you may use it to stop the
carousel. Use Actions class to move over to the carousel. Once it
stops you may click on it.
If you want a specific slide, you can click on dots or any other navigator, like prev/nxt, to reach your slide and then click it.
The sure shot way to click your specific slide, without worrying about whether it is displayed or not is to use Javascript to click it (Which I had done in my case although I had also implemented 2nd way but I found javascript the simplest solution).
Why are the actions divided?
I would recommend the following:
driver.find_element(:xpath,"xpath").click()
so it will find the object and click on it.
Another thing you can do, as we doing in selenium with java that put the implicitlyWait according to the time on which your button came back after one rotation; now perform click just after implicitlyWait
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// Suppose a rotation of button takes 30 sec
driver.findElement(By.xpath("/html/body/div[2]")).click();
// action performs on the element
In ruby you have to use this type of syntax
#driver.manage.timeouts.implicit_wait = 30