C#.Net | Java | |
---|---|---|
CI | ||
Package |
Copyright (c) 2017, EPAM Systems
License: GPL v3. GPL License
JDI – is the test Framework for UI test automation. It extends the Page Objects design pattern and introduces many additional elements along with implementation of its common usages.
The framework bases on the following concept: “Easy things should be easy, and hard things should be possible” Larry Wall (c).
Thus, all elements of the framework and all capabilities it provides have default realizations that would be used in most cases.
However, if your application performs some actions in a different way, you can override this behavior on any level - just for this element, for all elements with the same type, or even customize the scenario of actions for all elements.
Similarly, you can use any external tools and frameworks for the relevant functionality - different loggers, reporting tools, drivers test runners, and asserters.
We strive to make the test process easier and full of joy.
Enjoy to us! :)
Lets implement simple login scenario with JDI on our test site (https://epam.github.io/JDI/)
- Open Login page
- Login as user
- Check that homePage opened
Result you can see here
Note: you can use this already predefined test project template for all your new projects
First of all you just need to add dependency for jdi-web into your new Java test project
<dependency>
<groupId>com.epam.jdi</groupId>
<artifactId>jdi-uitest-web</artifactId>
<version>1.0.71</version>
</dependency>
Note: if you download example project via link this Pages already exist in \src\main\java\org\mytests\uiobjects\example
Pages structure:
@JSite(domain = "https://epam.github.io/JDI/")
public class JDIExampleSite extends WebSite {
public static HomePage homePage;
public static LoginForm loginForm;
@FindBy(css = ".profile-photo")
public static Label profilePhoto;
public static void login() {
profilePhoto.click();
loginForm.loginAs(new User());
}
}
Note: all fields and methods on your Site page are STATIC
Then setup HomePage (you can put here all elements related to Home Page. All elements on pages are NOT static)
@JPage(url = "/index.htm", title = "Index Page")
public class HomePage extends WebPage {
}
Setup Login form and entity User for it
public class User {
public String name = "epam";
public String password = "1234";
}
public class LoginForm extends Form<User> {
@FindBy(id="Login")
public TextField name;
@FindBy(id="Password")
public TextField password;
@FindBy(css="[type=submit]")
public Button enter;
}
Note: all fields on form are NOT static
See in \src\test\resources\test.properties
driver=chrome
timeout.wait.element=10
driver.getLatest=true
and logging properties in \src\test\resources\log4j.properties
@BeforeSuite(alwaysRun = true)
public static void setUp() throws Exception {
WebSite.init(JDIExampleSite.class);
logger.info("Run Tests");
}
@Test
public void loginExample() {
homePage.open();
login();
homePage.checkOpened();
}
Right click on test and choose Run
Open Maven Window (View > Tool Windows > Maven Projects)
And run allure:report (jdi.examples > Plugins > allure > allure:report)
@Test(dataProvider = "attendees", dataProviderClass = AttendeesProvider.class)
public void fillFormExample(Attendee attendee) {
sendCVPage.open();
cvForm.submit(attendee);
// Check
Assert.contains(() -> jobDescriptionPage.captcha.getAttribute("class"), "form-field-error");
}
- Open SendCV page
- Submit cv form with your attendee data
- Check that Form not sent because captcha field has an error
@Test
public void getTableInfoExample() {
jobsPage.open();
Assert.isFalse(jobsList::isEmpty);
Assert.areEquals(jobsList.columns().count(), 4);
Assert.areEquals(jobsList.rows().count(), 2);
Assert.areEquals(jobsList.getValue(),
"||X||JOB_NAME|JOB_CATEGORY|JOB_LOCATION|APPLY||\n" +
"||1||QA Specialist|Software Test Engineering|St-Petersburg, Russia|Apply||\n" +
"||2||Senior QA Automation Engineer|Software Test Engineering|St-Petersburg, Russia|Apply||");
}
- Open Jobs page
- Verify data in jobsList table
- Table has records
- Columns amount equal 4
- Rows amount equal 2
- Table structure is correct
@Test
public void searchInTableExample() {
jobsList.row(withValue("Senior QA Automation Engineer"), inColumn("JOB_NAME"))
.get("APPLY").select();
// Check
jobDescriptionPage.checkOpened();
}
- Wait while table have some Rows
- Get first row where value in column "JOB_NAME" equals to "Senior QA Automation Engineer"
- For this row select cell in Column APPLY
@Test
public void searchByMultiCriteriaInTableExample() {
MapArray<String, ICell> firstRow = jobsList.rows(
"JOB_NAME=Senior QA Automation Engineer",
"JOB_CATEGORY=Software Test Engineering")
.first().value;
Assert.areEquals(firstRow.get("JOB_LOCATION").getText(), "St-Petersburg, Russia");
}
- Get first row where value in column "JOB_NAME" equals to "Senior QA Automation Engineer" AND value in column "JOB_CATEGORY" equals to "Software Test Engineering"
- For this row select cell in Column APPLY
@Test
public void matcherExamples() {
Assert.contains("Test Text", "Text");
Assert.matches("1352-423-85746", "\\d{4}-\\d{3}-\\d{5}");
}
Just add '() -> ' to your Assert and wait some result from service or page loading (example fails if you remove '() ->' operator)
private int i = 0;
private String[] searchResults = new String[] { "Iphone 4", "Iphone 5S", "Iphone 6" };
private String getNext() {
if (i == 3) i = 0;
return searchResults[i++];
}
@Test
public void waitAssertsExample() {
Assert.areEquals(() -> getNext(), "Iphone 6");
Assert.contains(() -> getNext(), "Iphone 5");
Assert.matches(() -> getNext(), ".*S");
}
@Test
public void listAssertsExample() {
Assert.assertEach(searchResults).contains("Iphone");
Assert.assertEach(searchResults).matches("Iphone \\d.*");
Assert.arrayEquals(searchResults,
new String[] { "Iphone 4", "Iphone 5S", "Iphone 6" });
Assert.listEquals(asList(searchResults),
asList("Iphone 4", "Iphone 5S", "Iphone 6"));
Assert.assertEach(searchResults).areDifferent();
Assert.assertEach(sameList).areSame();
Assert.isSortedByAsc(sortedListAsc);
Assert.isSortedByDesc(sortedArrayDesc);
}
@Test
public void exceptionAssertsExample() {
Assert.throwException(this::throwException, "Test Exception");
Assert.throwException(this::throwException, RuntimeException.class, "Test Exception");
Assert.hasNoExceptions(this::getNext);
}
See more Eamples here
@JSite(domain = "https://www.epam.com")
public class EpamSite extends WebSite {
@JPage(url = "/", title = "EPAM | Software Product Development Services")
public static HomePage homePage;
@JPage(url = "/careers", title = "Careers")
public static CareerPage careerPage;
...
@FindBy(css = ".tile-menu>li>a") // Menu with limited list of options described by enum Header menu
public static Menu<HeaderMenu> headerMenu;
@FindBy(css = ".tile-menu>li>a") // List of elements accessible only by index
public static List<Label> listMenu;
@FindBy(css = ".tile-menu>li>a") // List of elements with ability to access by name
public static Elements<Label> listMenu;
}
public class CareerPage extends WebPage {
@FindBy(className = "job-search-input") // Simple Text field
public ITextField keywords;
public IDropDown<JobCategories> category = new Dropdown<>( // Complex Dropdown with two locators
By.className("multi-select-filter"),
By.className("blue-checkbox-label"));
@FindBy(className = "career-location-box") // Simple Dropdown
public IDropDown<Locations> city;
@FindBy(className = "job-search-button") // Simple Button
public IButton selectButton;
}
public class AddCVForm extends Form<Attendee> {
@FindBy(css = "[placeholder='First Name']")
private ITextField name;
@FindBy(css = "[placeholder='Last Name']")
private ITextField lastName;
@FindBy(css = "[placeholder='Email']")
private ITextField email;
private IDropDown country = new Dropdown<>(
By.cssSelector(".country-wrapper .arrow"),
By.xpath("//*[contains(@id,'select-box-applicantCountry')]//li"));
private IDropDown city = new Dropdown<>(
By.cssSelector(".city-wrapper .arrow"),
By.xpath("//*[contains(@id,'select-box-applicantCity')]//li"));
@FindBy(css = ".file-upload")
private RFileInput cv;
@FindBy(css = ".comment-input")
private ITextArea comment;
@FindBy(xpath = "//*[.='Submit']")
private IButton submit;
@FindBy(xpath = "//*[.='Cancel']")
private IButton cancel;
}
<dependency>
<groupId>com.epam.jdi</groupId>
<artifactId>jdi-uitest-web</artifactId>
<version>1.0.67</version>
</dependency>
dependencies {
testCompile 'com.epam.jdi:jdi-uitest-web:1.0.39'
}
<ivy-module>
<dependencies>
<dependency org="com.epam.jdi" name="jdi-uitest-web" rev="1.0.39"/>
</dependencies>
</ivy-module>
<dependency>
<groupId>com.epam.jdi</groupId>
<artifactId>jdi-uitest-mobile</artifactId>
<version>1.0.67</version>
</dependency>
<dependency>
<groupId>com.epam.jdi</groupId>
<artifactId>jdi-uitest-gui</artifactId>
<version>1.0.67</version>
</dependency>
NOTE: You need to setup Java version 8 or higher (see instruction on Maven site or example here)
driver=chrome
timeout.wait.element=10
domain=https://www.epam.com/
driver.getLatest=true
search.element.strategy=strict | soft
browser.size=1800X1000
demo.mode=false | true
multithread=true
run.type=local | remote
screenshot.strategy=on fail | on | off
Add Nuget package "JDI.UIWeb" to your solution
Site: http://jdi.epam.com/
VK: https://vk.com/jdi_framework
You can ask your questions on StackOverflow with tag.
Mail: roman_iovlev@epam.com
Skype: roman.iovlev