Testing Google Translate With Selenium and Cucumber
Introduction and Prerequisites
The following is a walkthrough on using Cucumber and Selenium (Java) to perform a handful of tests on
Google Translate. This walkthrough will be using Chrome, but can be adapted for using other web drivers as well.
This tutorial assumes the following:
- Java JDK, Eclipse, Maven (which probably came with your version of Eclipse), Chromedriver, JUnit, and Selenium are installed. If not, see this tutorial.
- Cucumber is added to Eclipse. (In Eclipse, go to Help > Eclipse Marketplace > Search for Cucumber and install the extension.)
- You have your Chrome Driver file, chromedriver.exe, within a folder called chromedriver, which is inside another folder called drivers, which is in the main project directory. (If you run into issues with this step, make sure to compare the finished package explorer image in the Troubleshooting section against your own package explorer.)
- You have some familiarity with Java and the Eclipse environment.
Step 1. Create and Set Up Your Maven Project
In Eclipse, go to File > New > Other > Maven Project. Select Create a simple project (skip archetype selection) and use the default Workspace location. Name the GroupId and ArtifactId as
Translate-Tutorial
and leave the other settings as default. Click Finish.
Step 2. Set up your pom.xml File
Replace the contents of your pom.xml file with the following:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>GoogleTranslateTutorial</groupId>
<artifactId>GoogleTranslateTutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<cucumber.version>5.0.0-RC2</cucumber.version>
</properties>
<dependencies>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Step 3. Create and Complete Your Cucumber Features File
Right click on the
src/main/resources
folder in the Package Explorer. Select New > File and name it
Translate.feature
.
Fill in your Cucumber Feature file with the following code:
Feature: Google Translate French to English feature
In order to understand other languages I do not speak
As any Google user
I want to translate my text
Scenario Outline: Translate some basic French phrases
Given I am on the Google Translate page
When I enter <French> in Google Translate
Then I check for <English> in English
Examples:
| French | English |
| "Bonjour" | "Hello" |
| "Au revoir" | "Goodbye" |
| "Je ne comprends pas" | "I do not understand" |
Step 4. Create the Cucumber Step Definitions Class
Right click on the src > test > java folder in the Package Explorer. Select New > Other, and search for
Step
in the search, and select the Step-definition class.
In the window that appears, you will have to select the Source Folder. Select
/GoogleTranslateTutorial/src/test/java
. Name the package
googletranslate.steps
and make the class name
Steps
. Create the file, then paste the following code:
package googletranslate.steps;
// JUnit's import statement
import org.junit.Assert;
// Selenium's webdriver import statements
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
// Cucumber's import statements
import io.cucumber.java.After;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
public class Steps {
// Declare the driver
WebDriver driver;
@Given("I am on the Google Translate page")
public void i_am_on_the_google_translate_page() {
// Find the directory path your project is currently in, and navigate to the folder containing your
// chromedriver.exe. (This assumes your chromedriver.exe is located in your project files, in a folder
// called drivers/chromedriver. If it's not there, make sure to change this to your local path!
String projectPath = System.getProperty("user.dir");
System.setProperty("webdriver.chrome.driver", projectPath+"//drivers/chromedriver/chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://translate.google.com/");
}
@When("I enter {string} in Google Translate")
public void i_enter_french_in_google_translate(String French) throws Exception {
// Find the box with the ID of "source" on the Google Translate page, and submit a phrase in French.
// (This is pulled from the Cucumber scenario outline.) After that, wait 1 second for the page to
// load before moving on to the next step.
driver.findElement(By.id("source")).sendKeys(French);
Thread.sleep(1000);
}
@Then("I check for {string} in English")
public void i_check_for_the_translation_in_english(String English) {
// Check if the results box contains the English phrase (supplied from the Cucumber scenario).
boolean result = driver.getPageSource().contains(English);
Assert.assertTrue("The French sentence translated to '"+English+"'", result);
}
@After()
public void closeBrowser() {
// Close the browser when the tests are completed.
driver.quit();
}
}
Notice the selector used to pick the DOM element in
driver.findElement(By.id("source")).sendKeys(French)
. There are many different ways to select an element, and not all are created equal. This example uses an HTML ID selector. See How to Identify DOM Elements for a discussion on how to choose the best selector.
Step 5. Create the Maven Test File
Right click on the
src/test/java
folder and click New > Package. Name it
testrunners
.
When the package is created, right click on the new package and click New > File. Name it
googletranslateTest
. (Test must begin with a capital 'T' in order for Maven to find it.)
Paste the following code into the new file:
package testrunners;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
@RunWith(Cucumber.class)
@CucumberOptions(
features="src/main/resources/",
glue="googletranslate.steps",
plugin = {"pretty", "html:target/SystemTestReports/report.html"})
public class googletranslateTest {
}
Step 6. Run the Maven Test Suite
Right click on the
pom.xml
file, select Run As > Maven Test. This will generate an HTML test report under GoogleTranslateTutorial > target > SystemTestReports > report.html.
Troubleshooting
Chrome Driver isn't working / I don't know how to set up the packages
When this tutorial is fully completed, your package explorer should look like this:
Make sure to note the location of the chromedriver.exe!
One or two of my tests failed (but not all of them)
If this happens when you're running Maven Test from the pom.xml file, try running it again once or twice. The web pages may be timing out during the test and leading to failed tests. This will cause this to appear in the console:
Tests run: 3, Failures: 2, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11:23 min
[INFO] Finished at: 2020-10-03T18:10:27-05:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project GoogleTranslateTutorial: There are test failures.
You can see the (absurdly long!) time it took the tests to run. It shouldn't take this long, only a couple minutes at most -- run the test again and see if it works the second time around.
How to Identify DOM Elements
Trying to find unique locators is one of the most important parts of web automation. There are many different ways of locating the same DOM element, it's very important to always use the simplest one available. Your goal should be to be human readable, easily understood, and to choose something that's likely to stay consistent even when the web page is updated.
The following is a list of different selection identifiers in order of preference:
- ID (if it is a unique ID on the page)
- Name (if it is a unique name on the page)
- CSS class name
- CSS selector
- XPath without text/indexing
- Link or partial link text
- XPath with text/indexing
Getting the ID of the element is the best method (assuming the ID is unique, which it should be). IDs can be recognized in the development tools as:
<div id="myID"></div>
driver.findElement(By.id("myID"))
If an ID is not available, the second best method is to use the
name
HTML property (again, assuming the name is unique).
<div name="myName"></div>
driver.findElement(By.name("myName"))
If neither the ID or name are available, or neither of those are unique attributes (like they should be), you can use the CSS class name:
<div class="myClass"></div>
driver.findElement(By.className("myClass"))
If this isn't specific enough, you can use a class selector:
<div class="myFirstClass mySecondClass"></div>
driver.findElement(By.cssSelector(".myFirstClass.mySecondClass"))
You can also use the XPath:
<div id="myID"></div>
driver.findElement(By.xpath("//div[@id='myID']"))
Or by the link text, if the element is a link:
<a href="#">Link Text</a>
driver.findElement(By.linkText("Link Text"))
And finally -- and because it's so likely to change with website updates, it's not recommended -- you can use the XPath to find specific text on the page.
<div>My Div Text</div>
driver.findElement(By.xpath("//div[text()="My Div Text"]))
--
SelenaHunter - 03 Oct 2020