Selenide is a Junit-based test Those that can operate the browser and check whether the expected screen transition and data are displayed
environment Language: JDK 1.8
Added the following description to pom.xml
<dependencies>
<!-Omitted->
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>selenide</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
4.9: Latest version of Selenide as of 3/12/2018
If you have SpringBoot installed, the version of the library (Selenium) referenced by Selenide is old. The following additional settings are required to operate selenide
<dependencies>
<!-Omitted->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
If it is assumed to work with FireFox and Chrome, it worked only with the above settings
If you get other errors like NoClassDefFound
or NoSuchMethod
Check selenium-api dependencies and compare it with the locally enabled version.
If the browser to be started is other than FireFox, a Driver file (an executable file that receives the contents described in Selenide and operates the browser / acquires information) is required. Get the file that suits your environment from Download Sites and place it in a location that can be specified by Junit.
Follow the steps below to set the driver.
Set in the @Before
method
@Before
public void before() {
Configuration.browser = WebDriverRunner.CHROME;
//Chromeドライバのパスを設定(ここでは設定ファイルから取得)
System.setProperty("webdriver.chrome.driver", getClass().getResource(properties.getChromeDriver()).getPath());
ChromeOptions chromeOptions = new ChromeOptions();
//HeadLessモード指定
if (properties.isHeadless()) {
chromeOptions.addArguments("--headless");
}
Map<String, Object> chromePrefs = new HashMap<>();
//PopUp表示を抑制
chromePrefs.put("profile.default_content_settings.popups", 0);
//ダウンロードフォルダ指定(テストメソッドごとに格納パスを切り替える等任意で設定)
chromePrefs.put("download.default_directory", "/User/Temp/result/DownloadFile");
//ダウンロード先指定ダイアログ表示抑制
chromePrefs.put("download.prompt_for_download", false);
chromeOptions.setExperimentalOption("prefs", chromePrefs);
driver = new ChromeDriver(chromeOptions);
//WebDriverRunnerにDriverを指定
WebDriverRunner.setWebDriver(driver);
Configuration.fastSetValue = true;
//スクリーンショットの設定ディレクトリ設定
Configuration.reportsFolder = "/User/Temp/result/ScreenShot";
}
Each specification is described below.
If you specify the following, you can start Chrome in Headless Mode and check it with a browser. By making this specification, automatic verification can be performed even in an environment without a UI.
chromeOptions.addArguments("--headless");
In the following two lines, specify the directory when downloading the file Suppresses the dialog from being displayed when downloading.
//ダウンロードフォルダ指定(テストメソッドごとに格納パスを切り替える等任意で設定)
chromePrefs.put("download.default_directory", "/User/Temp/result/DownloadFile");
//ダウンロード先指定ダイアログ表示抑制
chromePrefs.put("download.prompt_for_download", false);
It will be reflected in the following part of the Chrome setting screen
Specify the save destination of the screenshot below (Screenshots will be described later)
//スクリーンショットの設定ディレクトリ設定
Configuration.reportsFolder = "/User/Temp/result/ScreenShot";
By specifying the following, when entering characters in the input tag, Specify the specified characters at once (If you do not specify the following, each character will be entered on the screen.)
Configuration.fastSetValue = true;
It is executed in the @After
method.
Exit the Driver with the following method
@After
public void after() {
driver.close();
}
Executed in the method of @Test
(similar to normal Junit)
First of all, as a rough flow
Selenide # open (String, Class)
Open the specified page as follows
ItemsPageObject itemsPage = Selenide.open("http://localhost:8080/items", ItemsPageObject.class);
The class (Object) that is the second argument and the return value is called PageObject
.
Get and operate Selenide elements in this PageObject
In the test method, it is recommended to judge the acquisition result and operate the screen via PageObject.
@Test
public void testItemList() throws Exception {
ItemspageObject itemsPage = Selenide.open("/items", ItemspageObject.class);
List<String> ret = itemsPage.getItemNames();
assertEquals("ItemCount", 2, ret.size());
}
In the above example, get the HTML element in ʻItemspageObject # getItemNames ()` Confirmation of the acquired contents is carried out in the Test method.
Get the element by describing the get method in Page object (class)
You can get the target element by using Selenide # $ (String)
After that, I will describe such a simple page as an example
<table>
<tr>
<th>Header1</th>
</tr>
<tr>
<td>Data1</td>
</tr>
<tr>
<td>Data1</td>
</tr>
</table>
You can get the whole <table>
tag by getting it as follows
public SelenideElement getTable(){
return Selenide.$("table");
}
If you want to get more child elements, you can get them as follows
public ElementsCollection getTableRows(){
//Tableの要素を取得
SelenideElement table = Selenide.$("table");
//子要素の一覧を取得
return table.$$("tr");
}
You can search for an element with the character string specified by SelenideElement Selenide # $ (String)
and get the first element that was obtained.
ʻElementsCollection Selenide # $$ (String) Searches for an element with the specified character string, and can be obtained from the element list that was obtained first. Since ʻElementsCollection
is an inherited class of ʻAbstarctList
You can inject the element by describing the acquisition method in @ FindBy
as follows for the PageObject field.
public class ItemspageObject extends SelenideBasePageObject {
@FindBy(how = How.TAG_NAME, using = "table")
private SelenideElement table;
@FindBy(how = How.TAG_NAME, using = "tr")
private ElementsCollection rows;
In the above case, when creating an instance of ʻItemspageObject, get the element from the startup page with tag name = "table" and set the value. If you want to get the child elements of the above
table, you can specify your own class instead of
SelenideElement`.
public class ItemspageObject extends SelenideBasePageObject {
@FindBy(how = How.TAG_NAME, using = "table")
private OriginalTable table;
ʻOriginalTable is created by inheriting ʻElementsContainer
as follows
public class OriginalTable extends ElementsContainer {
@FindBy(how = How.TAG_NAME,using = "tr")
private List<TableRow> tableRows;
If you want to inject multiple elements and want to specify your own class, declare it as List <T>
T
must be a class that inherits ʻElementsContainer`
public class TableRow extends ElementsContainer {
/**
* TableHeader
*/
@FindBy(how = How.TAG_NAME, using = "th")
private ElementsCollection headers;
I will explain the operation for the acquired element
To get the value enclosed in the tag of the specified element
Use String SelenideElement # getText ()
<th>Header1</th>
If you execute it for Elemet corresponding to the above "th" tag, you can get the character string "Header1".
To get the attribute value of the specified element, use String SelenideElement # getAttribute (String)
.
<a href="/users">Data2</a>
If you want to get the above "href" attribute, get it as follows.
SelenideElement aTag;
//中略
String hrefStr = aTag.getAttribute("href");
important point
In the case of href attribute, the value to be fetched is as follows
http: // loalhost: 8080 / users
(returns the interpreted absolute path instead of the relative path)
Specify a character string for the following character string input items
<a>Input:<input type="text" name="NAME"></a>
Implemented using SelenideElemnt # setValue (String)
//InputTagに文字列を設定
inputTag.setValue("aaaaa");
//設定した文字列は"SelenideElemnt#getValue()"で取得できる
assertEquals("InputTagValue", "aaaaa", inputTag.getValue());
Specify the file path for the following file selection items
<a>FileUp:<input type="file" name="FILE"></a>
//InputTagにファイルパスを設定
fileUpTag.uploadFile(new File("/User/Text.txt"));
The file is not actually uploaded when the above process is executed, only the file path is set in the item. (Upload is done only after submitting)
If you want to set a value for an item with type ='hidden'
, you will get an error using SelenideElemnt # setValue (String)
.
Therefore, set the value via JavaScript.
<input type='hidden' name='hiddenItem' value='HiddenValue' />
To set a value for the'hiddenItem'item in the above example, you can set the value by writing as follows.
String value = "setting value"
((JavascriptExecutor) webDriver).executeScript("document.getElementsByName('hiddenItem').item(0).value = '" + value + "';");
WebDriver for IE / FireFox / Chrome both inherits RemoteWebDriver
and
Since RemoteWebDriver
implements JavascriptExecutor
, it can be supported by a general browser.
Use File SelenideElemnt # download ()
to get the file referenced by the href attribute.
It is not possible to handle processing that includes intermediate processing such as operation with JavaScript
After clicking the button or link, check the download folder (specified in the settings in [Link destination](#Specify file download path)) and acquire the newly created file as a download file.
The following notes
.tmp
(Downloading state by Chrome-1).crdownload
(Downloading state by Chrome-2)You can get it by performing the above 1-4 judgments with the following sources.
/**
* Get the latest download file
*
* @return Latest download file
*/
public File getLatestDownloadFile() {
final File downloadDir = new File(getFileDownloadPath());
//ダウンロード完了まで10秒待機
WebDriverWait waitForUpload = new WebDriverWait(driver, 10);
waitForUpload.until(new ExpectedCondition<Boolean>() {
//ここの判定処理は、デフォルトで500ミリ秒ごとに実施
public Boolean apply(WebDriver _driver) {
//ファイル名からダウンロード中か否かを判定
return isDownloadFinish(getLatestFile(downloadDir));
}
});
//最新ファイルを取得
File retFile = getLatestFile(downloadDir);
//最新ファイルが取得できたら対象のファイルを返却
if (isDownloadFinish(retFile)) {
return retFile;
}
//出来なかったらNull返却
return null;
}
/**
* Determine if it is being downloaded
*
* @param target Target file
* @return Whether the download is complete
*/
private static boolean isDownloadFinish(File target) {
return target != null && !target.getName().endsWith(".crdownload") && !target.getName().endsWith(".tmp");
}
/**
* Get the latest file
*
* @param targetDir Download directory
* @return Latest download file
*/
private File getLatestFile(File targetDir) {
File[] downLoaededFiles = targetDir.listFiles();
//クリック前に保持したファイル数と変わっていなかったらNullを返却
if (downLoaededFiles == null || downLoaededFiles.length == resultFileCount) {
return null;
}
//ファイルの更新時間で比較し、最新のファイルを返却
Arrays.sort(downLoaededFiles, new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return file1.lastModified() <= file2.lastModified() ? 1 : -1;
}
});
return downLoaededFiles[0];
}
By specifying a listener (implementation class of WebDriverEventListener
) for WebDriverRunner as shown below, processing can be executed at the timing before clicking.
WebDriverRunner.addListener(new WebDriverListenerImpl());
The implementation class of WebDriverEventListener
is implemented like this (hold the number of files in the specified folder before clicking)
/**
* Implementation class of WebDriverEventListener
*/
public class WebDriverListenerImpl implements WebDriverEventListener {
//その他のメソッド群は省略
@Override
public void beforeClickOn(WebElement webElement, WebDriver webDriver) {
//クリック前に実績フォルダ配下のファイル数を取得する
baseClass.setResultFileCount(new File(" "/User/Temp/result/DownloadFile"").listFiles().length);
}
}