I got into a project which requires a WebGUI to be tested. Selenium is used for this in combination with Jenkins to schedule tasks and run the tests. All of this is handled by one server (Linux).
Regular tests work fine but WebGUI tests fail and I am supposed to make them work. However I'm very confused by the roles of Jenkins' Plugin "Selenium Grid" (is it even neccessary), the JUnit tests inside the project utilizing a selenium libary and the setup of the headless browser required.
What exactly are the roles of the plugin "Selenium Grid" for Jenkins and how does the Selenium libary communicate with a headless browser (Role of WebDrivers?)?
I already know about the Selenium hub and nodes but have no idea how to approach this.
I hope somebody can help me cleaning up my confusion...
A Selenium Grid can be used to set up a scalable automated browser environment. It is often used for automated GUI testing. It consists of a Hub and one or more Nodes.
A Selenium Hub should be started and the resulting URL should be stored.
Then a desired number of Selenium Nodes should be started with a reference to the Url of the Hub. The nodes will register themselves to the Hub.
Then you could use Selenium Java to create a RemoteWebDriver instance, optionally specifying the url of the Selenium Hub. This webdriver is just a Java API, the actual work will be done in the Selenium Node environment(s).
You can use the Java API to implement your desired operations on the WebDriver instance. When running, the code will delegate all calls to the running Selenium environment.
There are multiple ways to actually start the hub and nodes. A Jenkins Plugin could do it, you could use Docker, a local process, or many more. I'd advise to not bind your setup directly to Jenkins unless you are certain that you will never switch.
The Jenkins Selenium Plugin specifies the URL that you should create a WebDriver with:
new RemoteWebDriver(new URL("http://jenkins.mydomain:4444/wd/hub"), capability);
Where jenkins.mydomain will probably be the IP of your Linux server. Just above it is a line that says that it "also" accepts external nodes. I am not familiar with the plugin, so I dont know whether this means that it sets up one or more nodes itself by default.
taken from the following website.
https://wiki.jenkins.io/display/JENKINS/Selenium+Plugin
This plugin sets up Selenium Grid in the following way
On master, Selenium Grid Hub is started on port 4444, unless configured otherwise in Jenkins global configurations. This is where all your tests should connect to.
For each slave, necessary binaries are copied and Selenium RCs are started.
RCs and the Selenium Grid Hub are hooked up together automatically.
Now the question is do you need this?
This is upto the requirement of the project. You just need to ask this question to yourself
do you need to run tests in parallel (to cutdown time or for browser compatibility testing), either now or in near future.
Related
From within my app I want to hit a website and than perform user action. Currently am using webview but I think webdriver will be easy to use and correct approach.
Current code:
WebView browser = (WebView) view.findViewById(R.id.webview);
browser.getSettings().setJavaScriptEnabled(true);
browser.getSettings().setDomStorageEnabled(true);
browser.getSettings().setUserAgentString(`"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36");`
browser.setWebViewClient(new MyBrowser());
browser.loadUrl("https://myurl.com");
Issues with current code: Its hard to send key stores or use Xpath.
What am looking for?
Hit the website using driver and than click buttons etc. Pseudo code as follows:
chat=driver.find_element_by_xpath("/html/somepath")
chat.click()
time.sleep(2)
search=driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/div[1]/span/div/span/div/div[1]/div/label/input")
search.click()
I understand that this is possible using selenium/appium. But what am confused is does selenium/appium also needs a server that runs on a separate machine? I want to run all of the code in my app without external server or any more apps.
Can I just add lib which gives me access to apis like I showed above?
You can use the Selenium or Appium without any server. Both are plugins, which means they are basically open code or libraries. You call those objects on your local machine (or phone), you don't call an online remote API.
The Selenium and Appium helps to find elements on a web page or to find elements inside a mobile app. There is absolutely no need for a server here or remote machine.
So, YES, just add the lib which gives you access to api's like you showed above.
Selenium
Selenium in it's basic form doesn't needs any seperate server to run. Selenium along with it's wide range of tools and libraries that can support the automation of web browsers within the same machine ( i.e. localhost).
WebDriver
At the core of Selenium is WebDriver an interface to write instruction sets that can be run interchangeably in many browsers using each browser's native support for Test Automation. This can be achieved in three simple steps:
Installing the Selenium library
Installing the browser drivers
Writing your first Selenium script
Sample code block:
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.amazon.com/");
driver.findElement(By.cssSelector("input.nav-input[value='Go']")).click();
Selenium Grid
However, Selenium also supports a distribution server for scaling browser allocation. If your usecase include steps to run tests in parallel across multiple machines, then Selenium Grid would be your best bet.
Selenium Grid allows the execution of WebDriver scripts on remote machines (virtual or real) by routing commands sent by the client to remote browser instances. It aims to provide an easy way to run tests in parallel on multiple machines.
Selenium Grid would also allow you to run tests in parallel on multiple machines and to manage different browser versions and browser configurations centrally (instead of in each individual test).
Having said that, it does solves a subset of common delegation and distribution problems, but will may not be able to manage your infrastructure, and might not exactly suit to your specific need.
Appium
Similarly, Appium is an open-source tool for automating native, mobile web, and hybrid applications on iOS mobile, Android mobile, and Windows desktop platforms. Hybrid apps which have a wrapper around a webview is a native control that enables interaction with web content. Projects like Apache Cordova make it easier to build apps using web technologies that are then bundled into a native wrapper, creating a hybrid app.
Based on your question and your response comment to the answer provided by #undetectedSelenium, the following assumptions apply:
You are testing a browser within an android phone that is connected to a Windows machine via an adb server running on the Windows machine
The browser under test is Chrome
Install selenium as part of your project:
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.2</version>
</dependency>
</dependencies>
Sample code block based on your psuedo code and answer provided by #undetectedSelenium
System.setProperty(“webdriver.chrome.driver”, “C:\\path\\to\\chromedriver.exe”);
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption(“androidPackage”, “com.android.chrome”);
// By default if the following option is not applied, selenium will take the 1st available
// node provided by the adb server if multiple android devices are attached
options.setExperimentalOption("androidDeviceSerial", deviceId);
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.amazon.com/");
driver.findElement(By.cssSelector("input.nav-input[value='Go']")).click();
The deviceId variable needs to contain the uuid listed as a device from the adb server for the particular device under test, i.e.
options.setExperimentalOption("androidDeviceSerial", 95s572sp0478);
Also you will require the correct Chromedriver for your android device. Check the version of Chrome browser installed on the device and download the correct driver from here for your Windows machine Chromedriver Downloads. Then place into your desired directory and add the directory path into the code.
I have Selenium test which picks a file via native Windows file picker window. This is achieved by using Java Robot class. This works fine when the test runs with a normal session (i.e. with a GUI). However when running test on a Jenkins master node tests are performed from other user and there is no active desktop session in this case, and files cannot be picked.
Is there a way to deal with this without setting slave node with a GUI?
There are lot of articles which suggest all the same ways to deal with file picking, but none mention about dealing with Windows native file picker when running a test from master node (with different user).
Robot can't be used in a headless environment. It's a known limitation. So you have to use active desktop mode. The same is valid for tools like SikuliX / AutoIT.
We have developed selenium webdriver script with junit+java using eclipse on window 7. All the scripts are working as expected now we are using this script for load testing using Jmeter. However, while running script system open multiple browser (200) based on user thread and it create system to hang, is there any way to handle this or we can run script without opening browser. I have come across xvfb tool, but not able to get java api for this tool to plugin in eclipse.
We have also tried using HtmlUnitDriver but as it does not support javascript hence the test is getting failed, also we tried HtmlUnit and found same thing.
Note: that we have writen webdriver script to maintain display item of element (autocomplete, image) on screen.
It would be great if anyone can help or provide more inputs on this...
Firstly, do not integrate selenium scripts with JMeter for load testing! It's not a good approach to follow due to the obvious consequences that you have mentioned in your post. I followed a similar apporach in the beginning when I was new to JMeter and selenium but suffered a great deal when it came to running load tests that spawned too many browser instances which killed the OS.
You can go for HtmlUnitDriver or any headless browser testing tools out there with JMeter, but still, they will be running the browser internally in the memory. Moreover if your application is heavily using Javascript, it won't help.
So I would suggest that you record a browsing session with JMeter Proxy and modify the script (set of requests) according to your needs and play those requests alone, with number of threads.
From a higher level, you should be doing this:
Add a JMeter test plan, listeners, thread group and setup JMeter proxy and record a browsing session where you enter something into the autocomplete textbox and you get certain results.
Stop your proxy and take a look at all the requests that come under your thread group.
As far as I know, when it comes to autocomplete plugins, multiple
requests are sent everytime you enter a letter into the textbox. For
example, for the word 'stackoverflow':
Request1: q=s Request2: q=st Request3: q=sta and so on
Here you can simulate this effect by including words such that all
words have the same length which in turn will let you have same
number of requests to be sent to the server.
So in your test plan, you will pass one word per Jmeter thread. You
can pass the words to a request, from a csv file by using jmeter
parametrization.
This will be a much memory efficient way of load testing instead of using selenium with JMeter. I had asked a similar question. You can check out the responses.
I'm using the Java API of the Selenium WebDriver:
Is it possible to create multiple instances of the Selenium WebDriver from different threads simultaneously without conflict?
How do I change the path of the firefox installation directory that WebDriver uses if I installed firefox in a different directory?
How can I hide all the instances of the browsers(e.g firefox) that those threads started?
Thank you.
I can give you an answer to your first question.
Yes, you can run multiple driver instances simultaneously. However it is not recommended to run more than 5 or so instances at once in a single selenium server. Selenium Grid was designed specifically for this (it is bundled with the Selenium Server).
I created 2 test suites with Selenium IDE and I would like to run those test suites at the same time. Just like firing threads at the same time. Is it possible without entering programming ?
P.S : I couldn't open 2 selenium IDE in Firefox.
Thanks.
Altug.
No it's not possible. Selenium IDE takes over the firefox control. And this is similar to 2 users clicking into same window.
The rule is 1 Firefox = 1 Selenium IDE
For parallel run you can setup Selenium grid. But it's more complicated solution than Selenium IDE.
It is possible, you have to run multiple profiles of the Firefox browser. You can do it by command
firefox -p Profile_Name -no-remote
make use of profile manager if you need:
firefox -profilemanager -no-remote
You can run as many profiles simultaneously you want... or your memory can handle. For each profile you have to install Selenium addons separatedly.
You will have to use Selenium Grid