You might want to run a test that is hosted on GitLab. Instead of clone, build, and run the tests locally you would like to do it on a CI/CD application. Thankfully GitLab has the GitLab CI, where you can use it to run your pipeline.
Wherever you want to use: demonstrate a pipeline execution during a presentation, test your open source project, and other things you need, you can use only one platform like GitLab.
Most of the steps on a pipeline are done inside a container that does not have a GUI (Graphical User Interface), so you need to consider this.
When we run automated web tests we need a web browser like Google Chrome or Firefox. When we run the tests locally using Selenium WebDriver in any programming language it opens the browser and does the actions inside our test script.
Let’s talk about the code that you can execute locally first and, later on, runs it in the pipeline.
You must “tell” your browser that you want to run the tests on it in headless mode. I’m going to use Google Chrome for this.
The Selenium WebDriver Java library has a class ChromeOptions
, where you can “tell” the browser the configurations you would like to do. We need to add the ability to execute the tests in the headless mode, so we can use:
ChromeOptions options = new ChromeOptions(); | |
options.setHeadless(true) |
We must tell the ChromeDriver that we need to use this headless option, so we need to pass it as a parameter for the ChromeDriver class during the object creation. Take a look at the code snippet below:
@BeforeAll | |
static void webdrivermanagerSetup() { | |
WebDriverManager.chromedriver().setup(); | |
ChromeOptions options = new ChromeOptions(); | |
options.setHeadless(true); | |
driver = new ChromeDriver(options); | |
driver.get("https://github.com/bonigarcia/webdrivermanager"); | |
} |
On line 3 we have the chrome driver setup using the WebDriverManager, so we don’t need to be worried about configuring manually the driver.
On line 5 have the creation of the ChromeOptions
object, and setting the headless mode on line 6.
On line 8 we are creating the browser instance, passing the options as a parameter for the browser.
On line 10 we are accessing a page.
Now we have the browser set with the headless mode.
If you need to run your tests inside the GitLab CI a container with Java JDK, Maven and Google Chrome are necessary. A container that has all of this is necessary, so we need to find one.
If you try to run your web tests directly into a container without the web browser, in our case the Google Chrome, you will face this issue:
root/.m2/repository/webdriver/chromedriver/linux64/83.0.4103.39/chromedriver: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory
This part “libX11.so.6: cannot open shared object file” is telling us that we are trying to run something with a GIU, but no user interface or library (like X11 / Xvfb) was not found.
A detailed log error can be found here: https://gitlab.com/elias.nogueira/webdrivermanager-pipeline-test/-/jobs/581828359
Now we know that we need a container with an emulated GIU interface (X11).
We need to build or find a docker image we can use. I will use an existing one to make it easy to add and run for now.
One good thing about the GitLab CI is the ability to get open docker images on the Docker Hub. If you do a search for all the tools we need on a container you might found this one: docker-maven-chrome.
Now it’s time to create the .gitlab-ci.yml
file and use the docker image mentioned, so the image on the GitLab CI file will be:
image: markhobson/maven-chrome:jdk-11
The complete .gitlab-ci.yml file will be explained in the next session.
When you need to execute something, like we want to run out web tests hosted on GitLab, you must define the steps to be executed.
You can find a lot of materials and good practices about how to create the pipeline steps but, to make it clear and easy to follow, I will have only two steps: build and test.
So the build step will compile the code and download the necessary libraries and the test step will execute the tests.
Take a look at this pipeline:
image: markhobson/maven-chrome:jdk-11 | |
stages: | |
– build | |
– test | |
variables: | |
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" | |
cache: | |
paths: | |
– .m2/repository/ | |
– target/ | |
build: | |
stage: build | |
script: | |
– mvn compile | |
test: | |
stage: test | |
script: | |
– mvn test -Dtest=com.eliasnogueira.wdm.GithubWDMPageTest |
On line 1 we are using the docker image that has Java JDK 11, Maven, and Google Chrome.
On lines 3 to 5 we are defining the stages of the pipeline: build and test.
On lines 7 and 8 we are defining the local maven repository.
On lines 10 to 13, we are telling GitLab CI to cache the maven repo and the target folder. It will make the process faster after the first execution because all the necessary libraries and classes will be already there.
On lines 15 to 18, we are defining the build step running mvn compile
as the command to build it. You might use another maven lifecycle, but this one works ok for this purpose.
On lines 20 to 23, we are defining the test step running the tests via mvn test
, and adding as a property (-D
) the test class we want to run.
This post showed you how to run your Selenium WebDriver tests using the GitLab CI with a docker image that contains Google Chrome inside it.
Now, instead of run the tests locally, you can run it using a pipeline and make sure your code works anytime running it manually or during each pull request.
In short, the process is easy:
.gitlab-ci.yml
) adding the custom docker image and the steps you want to execute You can find a complete working project at https://gitlab.com/elias.nogueira/webdrivermanager-pipeline-test
You can use the GitLab Container Registry to deploy your custom docker image and use it in the pipeline.
I’ve created, in the same project example, a branch called gitlab-registry that has only two differences comparing to the code in the master branch:
Dokerfile
that is based on maven:3.6.3-jdk-11
image that installs Google Chrome. Click here to see the file..gitlab-ci.yml
using the custom image deployed on the GitLab Container Registry. Click here to see the file. More details about this approach can be found on the README file for the mentioned branch.
16 Comments
This is superb. Thanks for sharing. I am finding the gitlab solution from many days.
Awesome, Iām glad it was useful for you!
Useful one, thank ou.
This is really helpful! Thanks a lot!
However I have a question. I believe if we are using Actions Class to move to an element and the perform an interaction(click, drag and drop, etc), will it still work in headless mode? Is there a way we can run the non-headless version inside the container?
Thanks again
Hi Robert!
You are right! The Actions class works with the headless mode. The tricky part is that, sometimes, you might fail due to an
org.openqa.selenium.WebDriverException: Element is not clickable at the point
. It happens because the element is not “visible” on the screen, given the viewport. So, to solve this you can increase the screen resolution.There’s a container called elgalu where you can see that the browser is doing through a VNC connection.
Thanks!
Its working properly for the normal test cases. But i have test which connected to web url in that case its not working and its throwing a Connection_refused exception. any idea about the issue.
Hi Arjun,
I think you should only the connection refused if the pod/container cannot find the URL.
Did you try to hit an internal URL that’s behind a proxy?
sir
very informative article thanks you.
I have one doubt. Can we use testng instead of junit to run tests? if so please guide me how we can do?
Hi Rakesh,
Actually, you just need to remove the JUnit library and add TesNG as a new dependency.
Then re-import the @Test and that’s it.
It’s simple and helpful example to run selenium tests in GitLab CI. I am searching for sample project and found your shared project which is clear with details steps explanation. Will follow the instructions and sample code to run our automation scripts from GitLab CI. Thanks a lot for sharing. Pls keep posting it is really very helpful to the learners/explorers like me. š
Thank for sharing!
Can you dockerize your selenium maven then test in gitlab CI with one app running in docker container?
Hi,
If you would like to do it all together (the project, the browser, and the test execution) it’s possible, and the .gitlab-cy.yml file on the repo shows that.
If you want to have it separately I would recommend not dockerize the test project, as you need to run it (maybe) multiple times in different targets (browsers, configurations, etc.)
The following project has one example using the Zalenium approach https://github.com/eliasnogueira/selenium-java-lean-test-achitecture
HI, java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation that requires it. how i set up X11 DISPLAY variable. Also, how do I run database tests with CICD?
Hi Dil,
Could you give me more examples of what do you want to achieve?
I will able to help you if you provide me more information about it.
Best!
Hi Elias the content is very useful but I have one query that how we can use selenium in an webapp projects means how we can test the code in gitlab of maven webapp project??
Where we need to define the script for test??
Hi Manish,
It depends on how do you want to run the project on a web app. If it’s about adding the test in the same web app project and running it you might need to change the command to run the tests, using the automation tool that supports it.
Examples: if your web app is made using Javascript you might use a JS web test automation tool. If you do want to use Selenium WebDriver with Java for a JS web app you might need to somehow trigger the test from a separate project. It’s called Multi Pipeline: https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html