I am able to click on the required canvas node, but also needed to select the node prior to clicking '+' button attached to it
//get a reference to the diagram object
const diagram = go.Diagram.fromDiv(document.getElementsByClassName("diagram-component")[0])
//using the diagram object find a node by name
const node = diagram.findNodesByExample({text: "capeutil"}).first()
//once you have the node you can expand it with the following command
node.findObject('ButtonButton').click(null, {part:node});
Need to help to select node by text
Selenium implementation
public void test_node_selection(String nodeName){
sleep(5);
JavascriptExecutor js = (JavascriptExecutor) context.getDriver();
js.executeScript(
"const diagram = go.Diagram.fromDiv(document.getElementsByClassName('diagram-component')[0]);" +
"const node = diagram.findNodesByExample({text: '" + nodeName + "'}).first()" +
"diagram.select(node);");
}
If you have a reference to a node, you can select it by calling Diagram.select
diagram.select(node);
Note that this clears any other selection the Diagram may have.
Related
For a few days I try to find a simple solution for scroll inside a list view
Since that Appium Inspector not provide the all elements of the list (only by manualy swipe and refresh the inspector then the new elements with the new instance loads.
After research i find out the distance between list item is as follow:
Item Location= (15, 828)
Item Location= (15, 1209)
Item Location= (15, 1590)
So i guess that every click need to scroll 381 pixels down, after so many tries I cannot find solution for this part of code and will be happy if someone can help with that:
List<WebElement> list = driver.findElements(By.id("net.balink.diplomat.qa:id/btnAddToCart"));
System.out.println("List Size is= " + list.size());
for (int j = 0; j < list.size(); j++) {
WebElement listItem = list.get(j);
Point location = listItem.getLocation();
System.out.println("Location= " + location);
listItem.click();
//to do here: swipe 381 px down after any click, then re-initialize
//the listItem in order to get a new index - and the loop when
//theres no more list items
Thread.sleep(2000);
}
I am using the following method for scrolling screen:
public static MobileElement scrollElementByContentDesc(String scrollableList, String uiSelector, String textToSearchInList) {
return driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().resourceId(\"" + scrollableList + "\")).getChildByDescription("
+ "new UiSelector().className(\"" + uiSelector + "\"), \"" + textToSearchInList+ "\")"));
}
scrollableList is id of your scrollable List element,
uiSelector is the className of the item of list,
textToSearchInList can be any text that you need to search in the list. It can be any random text if your purpose is just to scroll till the end of the list.
Call this method from any method:
public void someMethod(){
//other code
try{
MobileElement element= scrollElementByContentDesc("your scrollableList id",
"uiSelector classname", "any text you need to find in the list);
}catch(Exception e){
//do nothing
}
}
If you want to swipe by co0rdinate, you can do like this.
import io.appium.java_client.TouchAction;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import java.util.concurrent.TimeUnit;
import static java.time.Duration.ofSeconds;
TouchAction action = new TouchAction(driver);
action.press(PointOption.point(115, 650)).waitAction(WaitOptions.waitOptions(ofSeconds(1)))
.moveTo(PointOption.point(115, 350)).release().perform();
Make sure to import correct library.
The more reliable approach is to use native UiAutomator way:
So first of all find parent view of your list elements with scrollable: true attribute in place. That definitely should be at least one.
Then use inspector to build & test your UiAutomator locator
MobileElement elementScrollTo = driver
.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()"
+ ".resourceId(\"android:id/list\")).scrollIntoView("
+ "new UiSelector().text(\"Some text\"));");
UiSelector has pretty rich API , check it and find what suits you best.
This approach is better than TouchActions as you are not dependent on device screen resolution/coordinates.
I'm using canvas (phaser.io game framework) to make games and would like to do selenium tests. Sadly I can't replay recorded actions on a canvas.
For example I can't replay the click on the button here https://phaser.io/examples/v2/input/button-open-popup
I get this in the log:
1.Trying to execute open on /examples/v2/input/button-open-popup... Success
2.Trying to execute selectFrame on index=0... Success
3.Trying to execute clickAt on css=canvas with value 422,502... Success
But nothing happens on the screen and the popup is not poping up.
Is there a problem with clicking on canvas through Selenium IDE or maybe I'm doing something wrong?
I did some automated tests for Phaser games.
Let's take an example, I have to click on a menu button.
The way I managed to click on the button precisely every time is that I created a html page, with the same width and height as my canvas ( first, I decided the size of the chrome window, for me I used 800x900, and then get the canvas size), and in my html page I only put javascript to output me the positions where I click.
So basically I created a html, with the same dimension as my canvas, and clicked on it at the approximate position of my canvas button.
Here is the code I've used for my tests:
var mainState ={
preload: function(){
},
create: function(){
game.stage.backgroundColor = '#71c5cf';
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
},
update: function(){
getcoordinates();
}
};
function getcoordinates(){
if (game.input.mousePointer.isDown){
var x = game.input.activePointer.position.x;
var y = game.input.activePointer.position.y;
console.log("x" + x, "y" + y);
var worldx = game.world.centerX;
var worldy = game.world.centerY;
console.log("world x" + worldx, "world y"+ worldy);
}
};
var game = new Phaser.Game(384,683, Phaser.CANVAS);
game.state.add('mainState', mainState);
game.state.start('mainState');
As for checking if my action was succesfull, I used JavascriptExecutor. And in Selenium I've created some functions that do just that, navigate to coordinates and execute click.
JA
Unable to scroll on following screens due to overlay of elements?
Jatin ยท 2 days ago
Scenario- After filling all the details , user need to scroll from "for how many people" to bottom...
Line of code -
driver.findElementByXPath("//android.widget.TextView[#text='Send enquiry']").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_dialog_send_button").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_date_text").click();
driver.findElementById("com.letsdogether.dogether:id/cancel").click();
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_date_text").click();
// driver.findElementById("com.letsdogether.dogether:id/date_picker_year").click();
// driver.findElementByXPath("//android.widget.TextView[#content-desc=\"2020\"]").sendKeys("2020");
driver.findElement(By.xpath("//android.view.View[#index='24']")).sendKeys("25");
driver.findElementByXPath("//android.widget.Button[#text='OK']").click();
driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\"Message (Optional)\").instance(0))");
-------- scrolling is not happening by this command or neither from below command
// driver.findElementsByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(text(\"Message (Optional)\"));");
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_decrease_seats_button").click();
WebElement buttonElement = driver.findElement(By.id("com.letsdogether.dogether:id/send_enquiry_increase_seats_button"));
int i;
for(i=0;i<=10;i++) {
buttonElement.click();
}
driver.findElementById("com.letsdogether.dogether:id/send_enquiry_dialog_send_button").click();
// driver.findElementById("com.letsdogether.dogether:id/send_enquiry_increase_seats_button").click();
This blog post does a good job of covering some of the ways you can scroll in Appium, specifically on Android. A few ways you can scroll to the bottom of your screen are:
With UiScrollable, using scrollIntoView() and passing the identifier for the scrollable container. For example:
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().resourceId(\"" + *scrollable container ID* + "\")).scrollIntoView("+ "new UiSelector().resourceId(\"" + *ID of the element you want to scroll to* + "\"))"));
With UiScrollable, just execute a scrollForward(). For example,
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().resourceId(\"" + *scrollable container ID* + "\")).scrollForward()"));
Last resort, you can always use TouchActions. For example,
TouchAction actions = new TouchAction(driver);
actions.press(startX,startY).waitAction(Duration.ofSeconds(1)).moveTo(endX, endY).release().perform();
You can determine the coordinates to begin and end your TouchAction either as a proportion of your screen size, or as specific coordinates from one element to another.
Google is your friend. Let me know if this helps!
DevExpress builds combo boxes in a very odd way. The standard identification built in to Selenuim and Watir (including Page Objects) does not see it as a Select List.
So how can you automate these successfully?
So as it turns out, DevExpress builds combo boxes as a text box with several layered tables associated with it but not under the text box in the HTML tree.
interactions are all done via embedded scripts.
I found the simplest way to automate this object is to identify the text box and the lowest table containing the list of items (3rd table down).
for example (using Watir and Page Objects)
table(:list,:id => 'ComboBoxValue_DDD_L_LBT')
text_field(:state, :id => 'ComboBoxValue_I') #:name => 'State')
I have not found a way to get better IDs at these levels, but we are working that issue.
Then your select code looks like this:
self.state_element.click
row = list_element.find { |row| row[0].text == value }
row.click
Note that with Selenium, you can execute arbitrary javascript in the client to query and set the control's state (if the client-side is enabled for the control). Here's how I did so to extract (and set) the selected text from a combobox named localeSelectList:
// unit test code, c#
[TestMethod]
public void SomeTestMethod()
{
IWebDriver ff = new FirefoxDriver();
ff.Navigate().GoToUrl(homeUrl);
// find the element as an iWebElement
IWebElement localeBox = ff.FindElement(By.CssSelector("#localeSelectList"));
Assert.IsTrue(localeBox.Enabled);
// get the text from the control via javascript
var locale = Util.GetControlText(ff, localeSelectList);
Assert.IsTrue(locale == "English");
// set the text in the control via javascript
Util.SetControlText(ff, localeSelectList, "German");
// verify the text was set
locale = Util.GetControlText(ff, localeSelectList);
Assert.IsTrue(locale == "German");
}
// helper methods, Util class
static public string GetControlText(IWebDriver driver, string controlName)
{
string script = string.Format("return {0}.GetText();", controlName);
var controlText = ((IJavaScriptExecutor)driver).ExecuteScript(script);
return controlText.ToString();
}
static public void SetControlText(IWebDriver driver, string controlName, string controlText)
{
string script = string.Format("{0}.SetValue('{1}');", controlName, controlText);
((IJavaScriptExecutor)driver).ExecuteScript(script);
}
It's not quite the same thing as interacting with the extensions via primitives (clicks, keystrokes, etc) as it won't fire the event handlers for these events, but if your extension uses 'valueChanged' events instead of primitive handlers it's pretty close to the same.
Also note: you can use client-side javascript to find and return elements using jquery/css selectors and ids, as follows:
IWebElement element = (IWebElement) ((IJavaScriptExecutor)driver).ExecuteScript("return $('#.myElementId');")
That's right with several layered tables, but I would like to add that they are only visible when combobox is clicked. First
var cmbParameterGruppen = webDriver.FindElement(By.Id("phContent_ParameterGruppenComboBox_I"));
cmbParameterGruppen.Click();
and then
var tblItems = webDriver.FindElement(By.Id("phContent_ParameterGruppenComboBox_DDD_L_LBT"));
var parameterGruppen = tblItems.FindElements(By.XPath(".//*"));
var count = parameterGruppen.Count;
Debug.WriteLine($"Count = {count}");
if(count > 0)
parameterGruppen[count - 1].Click();
I select hier last row.
I have a situation in Selenium , where we are launching new browser instance using Internet explorer driver .
normally the load URL is given in the same instance of IE that is launched this becomes the parent window , Now my issue is in parent window on click of a button a child window will open I need to give my second URL in child window which will continue to be my main page
The language we are using is Java
Used the below code to switch window from parent to child window
public static boolean handleMultipleWindows(WebDriver Driver) throws InterruptedException
{
Thread.sleep(4000);
String currentWindow= Driver.getWindowHandle(); // Storing parent window reference into a String Variable
System.out.println(" Check title " + Driver.getTitle() + Driver.getWindowHandles().size());
for (String popUpHandle : Driver.getWindowHandles()) {
if(popUpHandle.equalsIgnoreCase(currentWindow))
continue;
Driver.switchTo().window(popUpHandle);
String sTitle = Driver.getTitle();
but the problem in our application is the parent window gets close and when i try to play back the recording getting the below error
org.openqa.selenium.WebDriverException: Unable to get browser (WARNING: The server did not provide any stacktrace information).
Use method switchTo().window() method to switch between IE windows.
You didn't specify programming language that you use so my example is in Java:
//get window handlers as list
List<String> browserWindows = new ArrayList<String> (driver.getWindowHandles());
//switch to new window
driver.switchTo().window(browserTabs.get(1));
//do something
//then close window and get back
driver.close();
driver.switchTo().window(browserTabs.get(0));