Can I Automated Speed Test using Selenium? - selenium

I am using beta.speedtest.net to check my network speed. I want to automate this process using Selenium(open to other frameworks as well). This automation process consists of few steps
Clicking on Change Server link
Type my preferred server location
Choose the server of my choice
Run the test
Get the result of each test (in any way possible)
How I am proceeding
public void RunTheTest()
{
IWebDriver driver = new ChromeDriver();
driver.Manage().Window.Maximize();
driver.Navigate().GoToUrl("http://beta.speedtest.net");
driver.FindElement(By.LinkText("Change Server")).Click();
}
Unable to find any element that is critical for my process.

The LinkText won't work in your case because the text contains leading and trailing white spaces. Those may be Non-Breaking SPaces
So you have to go with xpath with contains or normalize-space
//a[normalize-space(text())='Change Server']
//a[contains(text(),'Change Server')]
If you want simple then go with className
btn-server-select
as there is only one element with such className

Try this:
driver.findElement(By.xpath("//a[#class='btn-server-select' and contains(text(), 'Change Server')]")).click();

Related

Selenium IDE Test Case Pass / Fail

I am new in using Selenium IDE. I'm writing this test case where User A clicks this link and then it should direct the user to the correct page. Unfortunately, the page returns:
An error occured. Message: script 'pp/agensi-list.phtml' not found in path (C:/htdffocs/star/application/views\scripts/**)
But on my selenium, it shows the test case has passed (it should fail).
Can someone tell me why?
Hi it is very easy to write test case results pass/fail using selenium with testng framework,please read from below link i have given clear examples.
How can I write Test Result (Pass/Fail) in Excel file using TestNG Framework with Selenium WebDriver?
For more with real time examples ,you can read write test case pass/fail in excel using testng
Simply you have to create Excel utility for fileinput stream and fileoutputstream classes as below and call that class into another classes using extends keyword
Excel Utility:
public class Excelutility {
#BeforeTest
public void exceloperation(){
FileinputStream file = new FileiinputStream("file path");
//do file input stream details here
Fileoutputstream newfile=new Fileoutputstream("filepath");
//do fileoutputstream details here like create workbook,create sheets etc
}
}
Another class:
public class operations{
#Test
public void openbrowser(){
//write driver operations here
//write excel operations using
if(Title.equalsIgnoreCase("HP Loadrunner Tutorial")){
Testcase="PASS";
}else{
Testcase = "FAIL";
}
Label l1=new Label(1,2,"status")
writablesh.addCell(l3);
}
The test is likely passing because you aren't verifying anything after the click.
If the test stops after the link is clicked then it will pass. You have to confirm that something happened. Look for a change in the CSS or perhaps even look for the message you listed above?

how to Pass command line argument ( baseURL) for selenium WebDriver

Kindly help.
i have created a runnable jar for my Selenium webDriver suite. now i have to test this in multiple environment( QA , Demo box, Dev ). But my manager doesnt what it to be hard coded like below
driver.get(baseUrl)
As the baseURl will change according to the need. My script is given to the build team. So all they will do in the command prompt is
java -jar myproject-1.0.1.jar
So my manager has asked me to send the baseUrl as a command line argument so that build team do not have to go to my script and manually change the baseUrl. They should be able to change the URL every time they run the script from the command line itself. Something like this
java -jar myproject-1.0.1.jar "http://10.68.14.248:8080/BDA/homePage.html"
Can somebody please guide me through this. Is it possible to send command line arguments to Selenium Web Driver driver.get(baseUrl)
Thanks in advance
From your question above I recon you want pass URL at runtime, means your URL changes time to time so beside hardcoded URL , you want pass at the time your automation code runs. So, let me give you 2 simple solutions.
You can send URL dynamically or at Run time by using javascript executor:
try{
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("var pr=prompt('Enter your URL please:',''); alert(pr);");
Thread.sleep(15000L);
String URL = driver.switchTo().alert().getText();
driver.switchTo().alert().accept();
driver.get(URL);
}catch(Throwable e)
{
System.out.println("failed");
}
Use this code in place of driver.get(); , so that a prompt box will appear when you run your code and within 15 secs or it will throw a error(you can change the time in Thread.Sleep) you will give the current Valid URL and hit Enter, the navigation will go to the URL. So that you can use different URL for same set of testscripts.
By using Scanner Class:
String url = "";
System.out.println("Enter the URL :");
Scanner s = new Scanner(System.in);
url = s.next();
s.close();
By using this you can give needed URL in your Console (If you are using Eclipse).
I recommend try Javascript excutor in your code and then create a runnable jar file and just run the Jar file, you will know and it will be the better solution than commandline URL passing . Let me know :)
Another way is to supply arguments this way -Durl=foobar.com and extract them in runtime like this
String URL= System.getProperty("url")

Selenium - echo Base URL

How can I read the current value of Base URL in Selenium IDE 2.8.0?
Please suggest a working version of following selenese:
echo ${BASEURL}
Take your instance of the IWebDriver and put .Url after it. This gets the current URL that the driver is associated with. Then you can use whatever output mechanism you want to use. So if you go with the echo...
echo ${driver.URL}
where driver equals your active selenium WebDriver instance. If you want just the root of the URL then you need to do a regex expression on the returned URL and look for the .com/.net/.org and chop anything after that off.
If you are using php you might want to look here: http://forums.phpfreaks.com/topic/175838-extract-base-url-from-entire-url/
1) Create IWebDriver instance
IwebDriver driver = new FireFoxDriver();
2) navigate to URL
driver.navigate().to("");
3) Print the URL
printline("The base URL is " + driver.URL);
(please ignore syntactical and language specific errors)

Selenium Grid on Multiple Browsers: should each test case have separate class for each browser?

I'm trying to put together my first Data Driven Test Framework that runs tests through Selenium Grid/WebDriver on multiple browsers. Right now, I have each test case in it's own class, and I parametrize the browser, so it runs each test case once with each browser.
Is this common on big test frameworks? Or, should each test case be copied and fine tuned to each browser in it's own class? So, if I'm testing chrome, firefox, and IE, should there be classes for each, like: "TestCase1Chrome", "TestCase1FireFox", "TestCase1IE"? Or just "TestCase1" and parametrize the test to run 3 times with each browser? Just wondering how others do it.
Parameterizing the tests into a single class per test case makes it easier to maintain the non-browser specific code, while duplicating classes, one for each browser case, makes it easier to maintain the browser-specific code. When I say browser specific code, for example, clicking an item. On ChromeDriver, you cannot click in the middle of some elements, where on FirefoxDriver, you can. So, you potentially need two different blocks of code just to click an element (when it's not clickable in the middle).
For those of you that are employed QA Engineers that use Selenium, what would be best practice here?
I am currently working on a project which runs around 75k - 90k tests on daily basis. We pass the browser as a parameter to the tests. Reasons being:
As you mentioned in your question, this helps in maintenance.
We don't see too many browser-specific code. If you are having too much of browser specific code, then I would say there is a problem with the webdriver itself. Because, one of the advantages of selenium/webdriver is write code once and run it against any supported browser.
The difference I see between my code structure and the one you mentioned in question is, I don't have a test class for each test case. Tests are divided based on the features that I test and each feature will have a class. And that class will hold all the tests as methods. I use testNG so that these methods can be invoked in parallel. May be this won't suite your AUT.
If you keep the code structure that you mention in the question, sooner or later maintaining it will become a nightmare. Try to stick to the rule: the same test code (written once) for all browsers (environments).
This condition will force you to solve two issues:
1) how to run the tests for all chosen browsers
2) how to apply specific browser workarounds without polluting the test code
Actually, this seems to be your question.
Here is how I solved the first issue.
First, I defined all the environments that I am going to test. I call 'environments' all the conditions under which I want to run my tests: browser name, version number, OS, etc. So, separately from test code, I created an enum like this:
public enum Environments {
FF_18_WIN7("firefox", "18", Platform.WINDOWS),
CHR_24_WIN7("chrome", "24", Platform.WINDOWS),
IE_9_WIN7("internet explorer", "9", Platform.WINDOWS)
;
private final DesiredCapabilities capabilities;
private final String browserName;
private final String version;
private final Platform platform;
Environments(final String browserName, final String version, final Platform platform) {
this.browserName = browserName;
this.version = version;
this.platform = platform;
capabilities = new DesiredCapabilities();
}
public DesiredCapabilities capabilities() {
capabilities.setBrowserName(browserName);
capabilities.setVersion(version);
capabilities.setPlatform(platform);
return this.capabilities;
}
public String browserName() {
return browserName;
}
}
It's easy to modify and add environments whenever you need to. As you can notice, I am using this to create and retrieve the DesiredCapabilities that later will be used to create a specific WebDriver.
In order to make the tests run for all the defined environments, I used JUnit's (4.10 in my case) org.junit.experimental.theories:
#RunWith(MyRunnerForSeleniumTests.class)
public class MyWebComponentTestClassIT {
#Rule
public MySeleniumRule selenium = new MySeleniumRule();
#DataPoints
public static Environments[] enviroments = Environments.values();
#Theory
public void sample_test(final Environments environment) {
Page initialPage = LoginPage.login(selenium.driverFor(environment), selenium.getUserName(), selenium.getUserPassword());
// your test code here
}
}
The tests are annotated as #Theory (not as #Test, like in normal JUnit tests) and are passed a parameter. Each test will run then for all the defined values of this parameter, which should be an array of values annotated as #DataPoints. Also, you should use a runner that extends from org.junit.experimental.theories.Theories. I use org.junit.rules to prepare my tests, putting there all the necessary plumbing. As you can see I get the specific capabilities driver through the Rule, too. Though you could use the following code right in your test:
RemoteWebDriver driver = new RemoteWebDriver(new URL(some_url_string), environment.capabilities());
The point is that having it in the Rule you write the code once and use it for all your tests.
As for Page class, it is a class where I put all the code that uses driver's functionality (find an element, navigate, etc.). This way, again, the test code stays neat and clear and, again, you write it once and use it in all your tests.
So, this is the solution for the first issue. (I know that you can do a similar thing with TestNG, but I didn't try it.)
To solve the second issue, I created a special package where I keep all the code of browser specific workarounds. It consists of an abstract class, e.g. BrowserSpecific, that contains the common code which happens to be different (or have a bug) in some browser. In the same package I have classes specific for every browser used in tests and each of them extends BrowserSpecific.
Here is how it works for the Chrome driver bug that you mention. I create a method clickOnButton in BrowserSpecific with the common code for the affected behaviour:
public abstract class BrowserSpecific {
protected final RemoteWebDriver driver;
protected BrowserSpecific(final RemoteWebDriver driver) {
this.driver = driver;
}
public static BrowserSpecific aBrowserSpecificFor(final RemoteWebDriver driver) {
BrowserSpecific browserSpecific = null;
if (Environments.FF_18_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new FireFoxSpecific(driver);
}
if (Environments.CHR_24_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new ChromeSpecific(driver);
}
if (Environments.IE_9_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new InternetExplorerSpecific(driver);
}
return browserSpecific;
}
public void clickOnButton(final WebElement button) {
button.click();
}
}
and then I override this method in the specific class, e.g. ChromeSpecific, where I place the workaround code:
public class ChromeSpecific extends BrowserSpecific {
ChromeSpecific(final RemoteWebDriver driver) {
super(driver);
}
#Override
public void clickOnButton(final WebElement button) {
// This is the Chrome workaround
String script = MessageFormat.format("window.scrollTo(0, {0});", button.getLocation().y);
driver.executeScript(script);
// Followed by common behaviour of all the browsers
super.clickOnButton(button);
}
}
When I have to take into account the specific behaviour of some browser, I do the following:
aBrowserSpecificFor(driver).clickOnButton(logoutButton);
instead of:
button.click();
This way, in my common code, I can identify easily where the workaround has been applied and I keep the workarounds isolated from the common code. I find it easy to maintain, as the bugs are usually being solved and the workarounds may or should be changed or eliminated.
One last word about executing the tests. As you are going to use Selenium Grid you will want to use the possibility to run the tests in parallel, so remember to configure this feature for your JUnit tests (available since v. 4.7).
We use testng in our organization and we use the parameter option that testng gives to specify the enviroment, i.e. the browser to use, the machine to run on and any other config that is required for env config. The browsername is sent through the xml file which controls what needs to run and where. It is set as a global variable. What we have done as an extra is, we have our custom annotations which can override these global variables i.e. if a test is very specifically only to be run on chrome and no other browser, then we specify the same on the custom annotation. So, no matter even if the parameter is say run on FF, if it is annotated with chrome, it would always run on chrome.
I somehow believe making one class for each browser is not a good idea. Imagine the flow changes or there is a bit of here and there and you have 3 classes to change instead of one. And if the number of browsers increase, then one more class.
What I would suggest is to have code that is browserspecific to be extracted out. So, if the click behavior is browser specific, then override to it to do appropriate checks or failure handlings based on browsers.
I do it like this but keep in mind that this is pure WebDriver without the Grid or RC in mind:
// Utility class snippet
// Test classes import this with: import static utility.*;
public static WebDriver driver;
public static void initializeBrowser( String type ) {
if ( type.equalsIgnoreCase( "firefox" ) ) {
driver = new FirefoxDriver();
} else if ( type.equalsIgnoreCase( "ie" ) ) {
driver = new InternetExplorerDriver();
}
driver.manage().timeouts().implicitlyWait( 10000, TimeUnit.MILLISECONDS );
driver.manage().window().setPosition(new Point(200, 10));
driver.manage().window().setSize(new Dimension(1200, 800));
}
Now, using JUnit 4.11+ your parameters file needs to look something like this:
firefox, test1, param1, param2
firefox, test2, param1, param2
firefox, test3, param1, param2
ie, test1, param1, param2
ie, test2, param1, param2
ie, test3, param1, param2
Then, using a single .CSV parameterized test class (that you intend to start multiple browser types with), in the #Before annotated method, do this:
If the current parameter test is the first test of this browser type, and no already open windows exist, open a new browser window of the current type.
If a browser is already open and the browser type is the same, then just re-use the same driver object.
if a browser is open of a different type that the current test, then close the browser and re-open a browser of the correct type.
Of course, my answer doesn't tell you how to handle the parameters: I leave that for you to figure out.

Textbox Restrictions(Special chars/Numeric etc) not working for selenium automated test execution

I am testing a web application where certain text fields have restrictions based on requirements (eg.Amount textfield disallows alphabets and special characters & Name textfield disallows Numeric and special characters.), So while trying manually in a browser the restrictions work fine. But while automating the same testcase such textfields accept all data(eg. alphabets(lowercase and upper case),digits,special characters.)...Means in automation no restricton works at all..I am writing automated tests using Selenium in Eclipse(testNG framework) and using SeleniumRC to run tests.
I would suggest to use RegExps for verifying strings format.
e.g. my veryfying of build version format
#Test
public void buildVersionFormatVerify() throws IOException {
String buildVersion = findElementByCssSelector("home.buildversion.label").getText().trim();
String extractedVer;
extractedVer = buildVersion.substring(buildVersion.indexOf(':')+1,buildVersion.length()).trim();
Assert.assertTrue("build version does not match regexp",extractedVer.matches("\\d.\\d\\s.\\s\\d{2}"));
}
another approach can be the following:
you enter a certain string which does not satisfy input format accordingly to functional spec. Then you can trigger somhow that input was accepted (no error messages appears or validator has not handled inproper input) and you can block the 'accepted input' not following to functional spec with assert
e.g.
Assert.assertFalse("improper input format",isElementPresent(By.xpath(...xpath of the error message...)));
IMHO, it is my vision of solution to this issue.