Selenide and bonigarcia - java

I'm trying to use Selenide and bonigarcia together with using multiple web driver, such as Chrome, Mozilla, Edge and etc.
This is what I've done:
public static Selenide driver;
public static void runBrowser(String browserName, String url) throws Exception {
if(browserName.equals("Chrome")) {
WebDriverManager.chromedriver().browserVersion(browserConfiguration.chromeVersion).setup();
Configuration.startMaximized = true;
driver.open(url);
}
else if(browserName.equals("Firefox")) {
WebDriverManager.firefoxdriver().browserVersion(browserConfiguration.firefoxVersion).setup();
Selenide.open(url);
}
else if(browserName.equals("Edge")) {
WebDriverManager.edgedriver().browserVersion(browserConfiguration.edgeVersion).setup();
driver.open(url);
} else {
throw new Exception("Something went wrong opening browser");
}
}
But, when I am trying to call that method with the parameter of "Firefox" or "Edge", it always runs on chrome. So, every time when I call that method, chromes web driver is running.
I've made it with Selenium, the difference between them is that instead of Selenide.open(url), I use WebDriver.get(url) and it works fine when I call a method with "Firefox" or "Edge" parameter.
Any ideas?
**EDIT: **
I added Configuration.browser = FirefoxDriverFactory.class.getName(); and now it looks like that: WebDriverManager.firefoxdriver().browserVersion(browserConfiguration.firefoxVersion).setup(); Configuration.browser = FirefoxDriverFactory.class.getName(); Selenide.open(url);
It will open any browser which I want, Chrome, Mozilla, Edge, etc.
But, somehow, I don't think that this is a real solution. I don't even know what have I done with adding FirefoxDriverFactory.class.getName() and why it is working now.

Selenide already includes WebDriverManager from bonigarcia.
You can just choose the browser either with
Configuration.browser = "firefox";
or setting SystemProperty selenide.browser, e.g. -Dselenide.browser=firefox
You don't need any Factories, WebDriverManager calls etc.

Related

TestBench fails to open browser

I'm trying to set up my first very simple UX test using Vaadin TestBench. To avoid the headache of downloading drivers and setting System.properties or PATH values, I'm also using the WebDriverManager library.
To make it a little trickier, our login page is a JSP that we will need to open and authenticate before being able to test the Vaadin application.
Here is the simple test I've been trying:
public class LoginIT extends TestBenchTestCase {
private static final String URL="http://localhost:8080/";
#Before
public void setup() throws Exception {
ChromeDriverManager.getInstance().setup();
setDriver(new ChromeDriver());
}
#After
public void tearDown() throws Exception {
if (getDriver() != null) {
getDriver().quit();
}
}
#Test
public void testLogin_success() {
getDriver().get(URL);
Assert.equals(URL, getDriver().getCurrentUrl());
WebElement usernameField = driver.findElement(By.name("username"));
}
}
The simple test above will pass on the currentUrl assertion. However, it fails to find the element.
I think I have two issues here.
The browser doesn't open/navigate to the URL. Chrome doesn't open a new tab/page when running the test if Chrome is already open. Alternatively, if I allow it to launch the browser it does so without opening a page (on Mac OSX) so I never can visually confirm it navigates to the URL.
I've tried with Firefox, which apparently has a lot of issues with Selenium, and PhantomJS, which has issues with a missing .lib file in the latest binary. With the WebDriverManager, I downgraded to PhantomJS 2.0 but it times out waiting for http://localhost:29436/status.
If it does "successfully" navigate to the URL, as Chrome says it does, it isn't able to find the element. This might be due to number 1?
If TestBench isn't able to handle the JSP login, then it will be useless for my application. Any help is greatly appreciated. What could I be doing incorrectly that is causing my issues?
Created a simple test example for this issue
https://github.com/rogozinds/testbenchexample
What version of Testbench you are using?
Can you try to run it without using ChromeDriverManager, just download
chromedriver https://sites.google.com/a/chromium.org/chromedriver/downloads
and add it to your system PATH.
getDriver().get(URL) - should at least open a new Chrome Window and navigate to URL. But as I understood that's not happening?
P.S I've tried your example with Testbench 5 without ChromeDriverManager and simple index.html file it works.

Java selenium click override or create own

Hei. I have been creating automated tests with selenium, but I have ran into some issues with IE the click not working. (Seems like a common issue where the driver just freezes and it won't timeout or anything).
As a workaround I created a method which uses javascript executor to do the click instead.
public static void IEClick(WebElement element) {
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
}
The issue I have is that I would have to rewrite all my tests in order to make them work on IE.
#Test
public void Simpletest(){
Frontpage.SearchBox.sendKeys("DeadPool");
Frontpage.GOButton.click();
Frontpage.FirstREsult.click();
}
Would have to be changed to
#Test
public void Simpletest(){
Frontpage.SearchBox.sendKeys("DeadPool");
IEClick(Frontpage.GOButton);
IEClick(Frontpage.FirstREsult);
}
This is a solution but this mean I would have to redo all my tests to handle this. Which seems a little too much. So I'm wondering is it possible to create my own click?
Desired solution
Frontpage.FirstREsult.MyClick();
Where in MyClick I have already handled all the cases with different browsers etc.So I could just search and replace the click with my own click.
1) At first you can get a browser name from capabilities and using js or native click depending on browser
Capabilities caps = ((RemoteWebDriver) driver).getCapabilities();
String browserName = caps.getBrowserName();
2) Also you can always use a js click. It's a very rare situation where you can need the native one

The screen is not navigating even the click() method is executed successfully in mobile web app using selenium web driver

I was trying to click a button on my mobile web app, using selenium web driver. The button is located, the text over the button can be derived and even the click event is performing well. But the navigation doesn't occur.
I tried with Click() method, sendKeys() method and also with script executor. But couldn't process further on.
CODE:
public class TestWeb
{
WebDriver driver;
private Selenium selenium;
#Before
public void setUp() throws Exception {
driver = new IPhoneDriver();
driver.get("http://10.5.95.25/mobilebanking");
}
#Test
public void TC() throws Exception {
System.out.println("page 1");
Thread.sleep(5000);
WebElement editbtn1 = driver.findElement(By.id("ext-comp-1018"));
String s1 = editbtn1.getText();
System.out.println(s1);
editbtn1.click();
editbtn1.sendKeys(Keys.ENTER);
((JavascriptExecutor)driver).executeScript("arguments[0].click;", editbtn1);
System.out.println("ok");
}
#After
public void tearDown() throws Exception {
System.out.println("*******Execution Over***********");
}
}
I tried click, sendKeys and ScriptExecutor separately and also combined. It is executing without any error but the navigation doesn't occur.
Does anybody can help me with some other ways to perform click function on the button?
Ram
This may not be your issue but I noticed "ext-comp-" and guess you are using extjs.
I'm using GXT and while finding by id worked for many things, on some submit buttons it didn't.
I had to use firebug in firefox to locate the element and copy the xpath.
Then I could click the element by
driver.findElement(By.xpath("//div[#id='LOGIN_SUBMIT']/div/table/tbody/tr[2]/td[2]/div/div/table/tbody/tr/td/div")).click(); // worked
It was failing silently for me too. My submit button has the id of LOGIN_SUBMIT so I don't know why the following failed but ....
driver.findElement(By.id("LOGIN_SUBMIT")).click();//failed
Edit:
Here is an exact example (case 1 of 2):
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']")));
//wait.until(ExpectedConditions.elementToBeClickable((By.id("gwt-debug-LOGIN_SUBMIT")))); <!-- id works as well
OK so the element is found. It will timeout and throw an exception if it is not.
Still, the following fails (under firefox, works with chrome) with no error and the page does not navigate.
driver.findElement(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']")).click();
//driver.findElement(By.id("gwt-debug-LOGIN_SUBMIT")).click(); <-- fails too
What I have to do is:
driver.findElement(By.xpath("//div[#id='gwt-debug-LOGIN_SUBMIT']/div/table/tbody/tr[2]/td[2]/div/div/table/tbody/tr/td/div")).click();
So my experience was that even if I found the element with xpath, clicking failed unless I used a complete xpath.
Here is another exact example (case 2 of 2):
I can find an element like so:
WebElement we = driver.findElement(By.xpath("//*[#id=\"text" + i + "\"]"));
I know I have found it because I can see the text via:
we.getText();
Still selecting by the path I found it fails.
//get outta town man the following fails
driver.findElement(By.xpath("//*[#id=\"text" + i + "\"]")).click();
In this case there is not more explicit xpath to try as in case 1
What I had to do was use css:
//bingo baby works fine
driver.findElement(By.cssSelector("div#text" + i + ".myChoices")).click();
Actually, I obtained the css path via firebug than shortened it.
//this is what I recieved
html.ext-strict body.ext-gecko div#x-auto-0.x-component div#x-auto-1.x-component div#x-auto-3..myBlank div#choicePanel1.myBlank div.x-box-inner div#text3.myChoices //text3 is the id of the element I wanted to select
Whether or not you can figure out your needed xpaths and css selectors, I don't know, but I believe I experienced exactly what you did.

Automating switching browsers when running Selenium-Java tests

I am currently working on a project using Java, Selenium and Testng. My overall goal is to test the functionality of a webpage over different web browsers. I have my Selenium code working and am able to run the test on Chrome and Firefox. However, I have to manually change the code to switch the browser. I do this by commenting out driver = new ChromeDriver();
I would like to edit my code so the test runs in Firefox and when that test is complete start the test in Chrome. Can someone please guide me in the right direction?
Here is a sample of what my code looks like:
WebDriver driver = null;
Selenium selenium = null;
#BeforeSuite
public void setup() throws Exception {
/// Chrome Driver ///
System.setProperty("webdriver.chrome.driver", "mac/chromedriver.exe");
//driver = new ChromeDriver();
/// Firefox Driver ///
driver = new FirefoxDriver();
}
#Test
public void testGoogle() throws Exception {
selenium = new WebDriverBackedSelenium(driver,"URL");
There could be quite a few ways of achieving this.
In the setup you can read a property and based on that you can instantiate the right driver.
String driverType = System.getProperty("driverType");
if ("firefox".equals(driverType))
driver = new FirefoxDriver().....
You can run the test twice, once with firefox property and then with chrome property.
Other option is to keep all the test in one class. Then extend this class by two classes, one for firefox setup and another for chrome setup. Then you can run both the subclass tests in a suite. They would run one after the another.

How do you get selenium to recognize that a page loaded?

In certain unknown situations selenium does not detect that a page has loaded when using the open method. I am using the Java API. For example (This code will not produce this error. I don't know of an externally visible page that will.):
Selenium browser = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com");
browser.start();
browser.open("http://www.google.com/webhp?hl=en");
browser.type("q", "hello world");
When the error occurs, the call to 'open' times out, even though you can clearly see that the page has loaded successfully before the timeout occurs. Increasing the timeout does not help. The call to 'type' never occurs, no progress is made.
How do you get selenium to recognize that the page has loaded when this error occurs?
I faced this problem quite recently.
All JS-based solutions didn't quite fit ICEFaces 2.x + Selenium 2.x/Webdriver combination I have.
What I did and what worked for me is the following:
In the corner of the screen, there's connection activity indicator.
<ice:outputConnectionStatus id="connectStat"
showPopupOnDisconnect="true"/>
In my Java unit test, I wait until its 'idle' image comes back again:
private void waitForAjax() throws InterruptedException {
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try {
if ("visibility: visible;".equals(
selenium.getAttribute("top_right_form:connectStat:connection-idle#style"))) {
break;
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
You can disable rendering of this indicator in production build, if showing it at the page is unnecessary, or use empty 1x1 gifs as its images.
Works 100% (with popups, pushed messages etc.) and relieves you from the hell of specifying waitForElement(...) for each element separately.
Hope this helps someone.
Maybe this will help you....
Consider the following method is in page called Functions.java
public static void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver,30);
try {
wait.until(expectation);
} catch(Throwable error) {
Assert.assertFalse(true, "Timeout waiting for Page Load Request to complete.");
}
}
And you can call this method into your function. Since it is a static method, you can directly call with the class name.
public class Test(){
WebDriver driver;
#Test
public void testing(){
driver = new FirefoxDriver();
driver.get("http://www.gmail.com");
Functions.waitForPageLoaded(driver);
}
}
When I do Selenium testing, I wait to see if a certain element is visible (waitForVisible), then I do my action. I usually try to use an element after the one I'm typing in.
Using 'openAndWait' in place of 'open' will do the trick.
From the website:
Many Actions can be called with the "AndWait" suffix, e.g. "clickAndWait". This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load.
Enabling the 'multiWindow' feature solved the issue, though I am not clear why.
SeleniumServer(int port, boolean slowResources, boolean multiWindow)
SeleniumServer server = new SeleniumServer(4444, false, true);
Any clarification would be helpful.
I've run into similar issues when using Selenium to test an application with iFrames. Basically, it seemed that once the primary page (the page containing the iframes) was loaded, Selenium was unable to determine when the iframe content had finished loading.
From looking at the source for the link you're trying to load, it looks like there's some Javascript that's creating additional page elements once the page has loaded. I can't be sure, but it's possible that this is what's causing the problem since it seems similar to the situation that I've encountered above.
Do you get the same sort of errors loading a static page? (ie, something with straight html)
If you're unable to get a better answer, try the selenium forums, they're usually quite active and the Selenium devs do respond to good questions.
http://clearspace.openqa.org/community/selenium_remote_control
Also, if you haven't already tried it, add a call to browser.WaitForPageToLoad("15000") after the call to open. I've found that doing this after every page transition makes my tests a little more solid, even though it shouldn't technically be required. (When Selenium detects that the page actually has loaded, it continues, so the actual timeout variable isn't really a concern..
Not a perfect solution, but I am using this method
$t1 = time(); // current timestamp
$this->selenium->waitForPageToLoad(30);
$t2 = time();
if ($t2 - $t1 >= 28) {
// page was not loaded
}
So, it is kind of checking if the page was not loaded during the specified time, so it is not loaded.
another idea is to modify AJAX API (to add some text after AJAX actions).
After ajax action was finished, before return, set invisible field to TRUE, selenium will find it and read as green-light
in html:
<input type='hidden' id="greenlight">
in selenium
if(driver.findElement(By.id("greenlight")).getAttr("value").equals("TRUE")){
// do something after page loading
}
If you page has no AJAX, try to seek footer of page (I also use Junit fail(""), you may use System.err.println() instead):
element.click();
int timeout =120;
// one loop = 0.5 sec, co it will be one minute
WebElement myFooter = null;
for(int i=0; i<timeout; i++){
myFooter = driver.findElement(By.id("footer"));
if(myFooter!= null){
break;
}
else{
timeout--;
}
}
if(timeout==0 && myFooter == null){
fail("ERROR! PAGE TIMEOUT");
}

Categories

Resources