์ ๋ ๋์์์ ์น ์๋ํ๋ฅผ ํ๋ฉด์, ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ๊ธฐ์ํด findElement ํจ์๋ฅผ ์ฌ์ฉํ๋ค. ์ด์ findElement ์์๋ HTML element์ ์์๊ฐ์ ์ธ์๋ก ์ฃผ์ด์ผ ํ๋ค. ์ด๋, HTML element Locator ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ๊ฐ์ ๊ฐ์ ธ์ค๋๋ฐ, ์ด๊ฒ์ By ํด๋์ค์ ์ธ์คํด์ค ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ค.
By ์ง์ ์?
By Locator ๋ผ๊ณ ๋ ํ๋ค. findElement(), findElements() ๋ฉ์๋๋ By์ง์ ์๋ฅผ ์ธ์๋ก ์ฃผ์ด ์น ์๋ฆฌ๋จผํธ๋ฅผ ๊ฐ์ ธ์จ๋ค.
์ง์ ์์ ์ข ๋ฅ๋ 8๊ฐ์ง๊ฐ ์๋ค. ID, Name, ClassName, LinkText, LinkText, LinkText์ ์ผ๋ถ๋ถ, XPath, CSS ์ ํ์์ด๋ค.
์ด์ ๊ฐ ์ง์ ์์ ์ฌ์ฉ๋ฒ์ ์์๋ณด์.
By.id()์ By.name()
- By.id() : ์น ์๋ฆฌ๋จผํธ์ ID ์์ฑ์ด ์์ผ๋ฉด ๊ฐ ์์ฑ์ ๊ณ ์ ํ๊ฒ ์๋ณํ ์ ์๋ค.
ID๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ์์ฑํ๊ฑฐ๋ ์ฑ์์ ๋์ ์ผ๋ก ์์ฑํ๋ค. ๋์ ์ผ๋ก ์์ฑํ๋ ID๋ ์๊ฐ์ด ์ง๋๋ฉด ๋ฐ๋๊ธฐ๋ ํ๋ค. ๋์ ID๋ ์๋ก๊ณ ์นจ ๋ฑ์ ์ก์ ์๋ ๋ฐ๋ ์ ์๋ค.
์ด๋ค ์น ํ์ด์ง์์ HTML ์์ ์ ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์๋ณด์.
<input id="query" name="query" type="text" title="๊ฒ์์ด ์
๋ ฅ" maxlength="255" class="input_text" tabindex="1"
accesskey="s" style="ime-mode:active;" autocomplete="off" placeholder="๊ฒ์์ด๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์." onclick="document
.getElementById('fbm').value=1;" value="" data-atcmp-element="">
์ ์ฝ๋์์ ๋ฒํผ์ id๋ ‘query’์ด๋ค. ์ ์ฝ๋์์ ๋ฒํผ์ name์ ‘query’์ด๋ค.
๊ฐ๋จํ ์์ ๋ก, ๋ค์ด๋ฒ ํํ์ด์ง์์ ๊ฒ์์ฐฝ์ ์ฐพ์์ '๊ฐ๋ฐฉ'์ ๊ฒ์ํ๋ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์๋ค.
public void byIdLocatorExample() {
WebElement searchBox = driver.findElement(By.id("query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
By.className()
๋ณดํต HTML ์๋ฆฌ๋จผํธ์๋ ์ฌ์ฉ์์ ์์ ์ ๋๊ธฐ์ํ ์คํ์ผ์ด ์ ์ฉ๋์ด ์๋ค. ์๋ฆฌ๋จผํธ์ ์คํ์ผ์ ์ ์ฉํ๊ธฐ ์ํด, ์ง์ ์๋ฆฌ๋จผํธ ํ๊ทธ์ ์คํ์ผ์ ์ ์ธํ๊ฑฐ๋, CSS ํ์ผ์ ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌํด class ์์ฑ์ผ๋ก ์๋ฆฌ๋จผํธ๊ฐ ์คํ์ผ์ ์ฐธ์กฐํ๋๋ก ํ๋ค.
์๋ฅผ ๋ค์ด, ์๋์ ๊ฐ์ด ๋ฒํผ์ style ์์ฑ์ CSS ํ์ผ์ ์ ์ธํ๋ค๊ณ ํ์.
.search-button{
width : 50px;
height : 50px;
}
์ ์ธํ ์คํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฒํผ ์๋ฆฌ๋จผํธ์ ์ ์ฉ๋๋ค.
- ์๋ฆฌ๋จผํธ๋ ์ฌ๋ฌ ๊ฐ์ class ์์ฑ์ ๊ฐ์ง ์ ์๋ค.
- ์๋์ ์ฝ๋๋ ‘button’๊ณผ ‘search-button’ ๋ ๊ฐ์ง ์์ฑ์ ๊ฐ์ง๋ค.
๋ ์ค์์ ์ ์ผํ ์๋ณ์๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ์ชฝ์ ์ ํํด์ ์ฌ์ฉํ์.
<button type="submit" title="Search" class="button search-button"><span><span>Search</span></span></button>
์์ ์ค๋ช ํ ๋ด์ฉ๊ณผ ํฉ์ณ์, ์น๋๋ผ์ด๋ฒ๊ฐ ํด๋์ค ์ด๋ฆ์ผ๋ก ๊ฒ์ ๋ฒํผ์ ์ฐพ์ ํด๋ฆญํ๋๋ก ํ๋ ์์ ๋ฅผ ์์ฑํด๋ณด์๋ค.
public void byClassNameLocatorExample() {
WebElement searchBox = driver.findElement(By.id("query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
WebElement searchButton =
driver.findElement(By.className("btn_submit"));
searchButton.click();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
By.linkText()์ By.partialLinkText()
By.linkText ์ง์ ์๋ HTML ๋งํฌ๋ฅผ ์๋ณํ ๋๋ง ์ฌ์ฉ ํ๋ค.
๋ค์ด๋ฒ ๋ฉ์ธ ํ์ด์ง์ '๋ด์ค' ์๋ฆฌ๋จผํธ ์์๋ฅผ ์นดํผํด๋ณด์.
<a href="https://news.naver.com/" class="nav" data-clk="svc.news">๋ด์ค</a>
By.linkText ์ง์ ๋ฐฉ์์ a ํ๊ทธ์ ํ ์คํธ('๋ด์ค')๋ก ์น ์๋ฆฌ๋จผํธ๋ฅผ ์๋ณํ๋ค.
๋ค์ด๋ฒ ๋ด์ค์ ๋ฐฉ๋ฌธํด์ ํ์ดํ์ด ๋ง๋์ง ๋น๊ตํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์๋ค.
public void byLinkTextLocatorExample() {
WebElement myAccountLink =
driver.findElement(By.linkText("๋ด์ค"));
myAccountLink.click();
assertThat(driver.getTitle())
.isEqualTo("๋ค์ด๋ฒ ๋ด์ค");
}
By.partialLinkText ์ง์ ์๋ ๋งํฌ ํ ์คํธ์ ์ผ๋ถ ๋จ์ด๋ง ์๊ณ ์์๋, ์๋ฆฌ๋จผํธ๋ฅผ ์๋ณํ ์ ์๋ค.
๋ค์ด๋ฒ ๋ฉ์ธ์ '์ผํLIVE'์ ์ง์ ํ๋ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด์๋ค.
public void byPartialLinkTextLocatorExample() {
WebElement orderAndReturns =
driver.findElement(By.partialLinkText("์ผํL"));
orderAndReturns.click();
assertThat(driver.getTitle())
.isEqualTo("๋ค์ด๋ฒ ์ผํ๋ผ์ด๋ธ");
}
By.tagName()
tagName์ ํ๊ทธ ์ด๋ฆ์ผ๋ก ์๋ฆฌ๋จผํธ๋ฅผ ์ง์ ํ๋ ๋ฉ์๋์ด๋ค.
์๋ฅผ ๋ค์ด ํํ์ด์ง์์ button ํ๊ทธ๋ช ์ผ๋ก ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ๋ ๊ฒ์ธ๋ฐ, ํํ์ด์ง์๋ ์ฌ๋ฌ ๊ฐ์ ๋ฒํผ์ด ์๊ธฐ๋๋ฌธ์ ์ฌ๋ฌ ๊ฐ์ ๋ฒํผ์ด ๋ฐํ๋๋ค. ์๋ ์ด ๊ฒฝ์ฐ์๋ findElements() ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐ๋์งํ๋ค.
๋ค์ด๋ฒ์์ ๋ค์ด๋ฒ ๊ฐ๋ฐ์ ์ผํฐ๋ก ์ด๋ํ ๋ค์ > ๋ชจ๋ a ํ๊ทธ์ ๋งํฌ ํ ์คํธ๋ฅผ ์ถ๋ ฅํด๋ณด์.
public void byTagNameLocatorExample() {
WebElement orderAndReturns =
driver.findElement(By.linkText("๋ค์ด๋ฒ ๊ฐ๋ฐ์ ์ผํฐ"));
orderAndReturns.click();
//a ํ๊ทธ๋ฅผ ๊ฐ์ง ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ๋๋ค.
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Found links:" + links.size());
// Java 8 Streams API๋ก ํํฐ๋งํด์ ๋งํฌ ํ
์คํธ๊ฐ ์๋ ๋งํฌ์ ๋งํฌ ํ
์คํธ๋ง ์ถ๋ ฅํ๋ค.
links.stream()
.filter(elem -> elem.getText().length() > 0)
.forEach(elem -> System.out.println(elem.getText()));
}
- ๊ทธ๋ฅ ๋ค์ด๋ฒ ๋ฉ์ธํ์ด์ง์์ a ํ๊ทธ๋ฅผ ์ฐพ๋ ์ฝ๋๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document (Session info: chrome=105.0.5195.125)
ใด ํ์ด์ง๋ฅผ ๋๋ฌด ๋นจ๋ฆฌ ๋ถ๋ฌ์์ ์ธ ๊ฒ ๊ฐ์๋ฐ, ํด๊ฒฐ๋ฐฉ๋ฒ์ ๋ฐ๋ก ์์๋ณด์.
By.xpath()
xpath๋ XML path์ ์ค์๋ง๋ก XML ๋ฌธ์๋ฅผ ๊ฒ์ํ๋ ์ฟผ๋ฆฌ ์ฉ์ด์ด๋ค.
- Xpath ๋ฌธ๋ฒ
ใด ๋ฃจํธ ์๋ฆฌ๋จผํธ: //
ใด div ์๋ฆฌ๋จผํธ: //div
ใด div ์๋ฆฌ๋จผํธ ์์ ์๋ link ํ๊ทธ : //div/a
ใด ํ๊ทธ ์์ ์๋ ์๋ฆฌ๋จผํธ ๋ชจ๋ ์ง์ : //div/*
ใด ๋ฃจํธ๋ถํฐ ์์ ์๋ฆฌ๋จผํธ๋ก ๋ด๋ ค์ค๋ div ์๋ฆฌ๋จผํธ ์ง์ : //*/*/div
ใด ํน์ ์๋ฆฌ๋จผํธ๋ฅผ ์๋ณ : //*/div/a[@id=’ attrValue’] (์์ฑ ๊ฐ์ ์ฌ์ฉ)
ใด ํ์ฌ ์๋ฆฌ๋จผํธ ๋ถํฐ ์ด์ด์ ์๋ณ : ./div/a/div
๋ฐ๋ก ์์ ๋ฅผ ์์ฑํด๋ณด์. ๋ค์ด๋ฒ ๊ฒ์ ์ฐฝ์ xpath๋ก ๊ฐ์ ธ์์ '๊ฐ๋ฐฉ'์ ๊ฒ์ํ๋ ์์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์๋ค.
public void byXPathLocatorExample() {
WebElement searchBox =
driver.findElement(By.xpath("//*[@id=\"query\"]"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
์๋ฆฌ๋จผํธ ์๋ณ์ด ํ์ํ ๋๋ง๋ค ์น๋๋ผ์ด๋ฒ๋ ์ ์ฒด ํ์ด์ง๋ฅผ ์ค์บํ๋๋ฐ, ์ด๋ฐ ๊ณผ์ ์ ๋งค์ฐ ๋นํจ์จ ์ ์ด๋ค. ์ฆ, XPath๋ฅผ ์์ฃผ ์ฌ์ฉํ๋ฉด ํ ์คํธ๋ ์ ์ ๋๋ ค์ง๋ค.
By.cssSelector()
By.cssSelector() ๋ฉ์๋๋ By.xpath()์ ์ฌ์ฉ๋ฒ์ด ๋น์ทํ์ง๋ง, ์๋๊ฐ ๋ ๋น ๋ฅด๋ค.
- ์์ฃผ ์ฌ์ฉํ๋ ๋ฌธ๋ฒ
ใด id๊ฐ flrs ์ธ div ์๋ฆฌ๋จผํธ : #flrs
ใด ์ฐพ์๋ธ div์ ์์ ์๋ฆฌ๋จผํธ์์, anchor ์๋ฆฌ๋จผํธ๋ฅผ ์๋ณ : #flrs > a
ใด ๋ค์, ์์ฑ ๊ฐ์ผ๋ก anchor ์๋ฆฌ๋จผํธ๋ฅผ ์๋ณ : #flrs > a[a[herf=”/intl/en/about.html”]]
์์ XPath๋ฅผ ์ฌ์ฉํ ์์ ๋ฅผ cssSelector๋ก ์ง์ ์๋ฅผ ๋ฐ๊พธ์ด ์คํํด๋ณด์.
public void byCssSelectorLocatorExample() {
WebElement searchBox =
driver.findElement(By.cssSelector("#query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
์ ์ฒด ์ฝ๋๋ฅผ ์คํํด๋ณด์.
์ดํด๋ฆฝ์ค ํ๋ก์ ํธ์ TestNG class ์์ฑํ ํ, ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
package com.example;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.SourceType;
import org.testng.annotations.*;
import javax.xml.bind.SchemaOutputResolver;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class NaverLocationTest {
WebDriver driver;
@BeforeClass
public void setup() {
System.setProperty("webdriver.chrome.driver",
"./src/test/resources/drivers/chromedriver");
driver = new ChromeDriver();
}
@BeforeMethod
public void navigate() {
driver.get("https://www.naver.com/");
}
@Test
public void byIdLocatorExample() {
WebElement searchBox = driver.findElement(By.id("query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
@Test
public void byClassNameLocatorExample() {
WebElement searchBox = driver.findElement(By.id("query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
WebElement searchButton =
driver.findElement(By.className("btn_submit"));
searchButton.click();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
@Test
public void byLinkTextLocatorExample() {
WebElement myAccountLink =
driver.findElement(By.linkText("๋ด์ค"));
myAccountLink.click();
assertThat(driver.getTitle())
.isEqualTo("๋ค์ด๋ฒ ๋ด์ค");
}
@Test
public void byPartialLinkTextLocatorExample() {
WebElement orderAndReturns =
driver.findElement(By.partialLinkText("์ผํL"));
orderAndReturns.click();
assertThat(driver.getTitle())
.isEqualTo("๋ค์ด๋ฒ ์ผํ๋ผ์ด๋ธ");
}
@Test
public void byTagNameLocatorExample() {
WebElement orderAndReturns =
driver.findElement(By.linkText("๋ค์ด๋ฒ ๊ฐ๋ฐ์ ์ผํฐ"));
orderAndReturns.click();
//a ํ๊ทธ๋ฅผ ๊ฐ์ง ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ๋๋ค.
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Found links:" + links.size());
// Java 8 Streams API๋ก ํํฐ๋งํด์ ๋งํฌ ํ
์คํธ๊ฐ ์๋ ๋งํฌ์ ๋งํฌ ํ
์คํธ๋ง ์ถ๋ ฅํ๋ค.
links.stream()
.filter(elem -> elem.getText().length() > 0)
.forEach(elem -> System.out.println(elem.getText()));
}
@Test
public void byXPathLocatorExample() {
WebElement searchBox =
driver.findElement(By.xpath("//*[@id=\"query\"]"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
@Test
public void byCssSelectorLocatorExample() {
WebElement searchBox =
driver.findElement(By.cssSelector("#query"));
searchBox.sendKeys("๊ฐ๋ฐฉ");
searchBox.submit();
assertThat(driver.getTitle())
.isEqualTo("๊ฐ๋ฐฉ : ๋ค์ด๋ฒ ํตํฉ๊ฒ์");
}
@AfterClass
public void tearDown() {
driver.quit();
}
}
pom.xml ํ์ผ์ ์์กด์ฑ์ ์ถ๊ฐํ๋ค.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
Test All์ ๋๋ฅด๊ณ , ์คํ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด์. 7๊ฐ ๋ฉ์๋๊ฐ ๋ชจ๋ PASS ํ๋ค.
![all-pass](https://blog.kakaocdn.net/dn/benV9N/btsa8ibrT4t/ySwaOGTe1tfUlGBWvKJRx0/img.png)
ํจ๊ป ๋ณด๋ฉด ์ข์ ๊ธ
Selenium ์น ์๋ฆฌ๋จผํธ ์ฐพ๊ธฐ FindElement , java
์น ์๋ํ๋ฅผ ์ํด์ ์น์๋ฆฌ๋จผํธ ์์๋ฅผ ์ฐพ๋ ๊ฒ์ ์์ฃผ ์์ฃผ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค. ์ ๋ ๋์์์๋ FindElement, FindElements ๋ฅผ ํตํด ์์ฃผ ์ฝ๊ฒ ์น ์๋ฆฌ๋จผํธ๋ฅผ ์ฐพ์๋ผ ์ ์๋ค. ์ค๋์ ์ด ๋ถ๋ถ์ ํฌ์คํ
dev-yujin.tistory.com
'SQA > Automation' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Selenium ์ฌ์ฉ์ ์ก์ ์คํ sendKey clear submit (0) | 2023.04.20 |
---|---|
Selenium ์๋ฆฌ๋จผํธ ์์ฑ ๊ฐ์ ธ์ค๊ธฐ HTML get ์์ฑ , java (0) | 2023.04.19 |
Selenium ์น ์๋ฆฌ๋จผํธ ์ฐพ๊ธฐ FindElement , java (0) | 2023.04.16 |
Maven ํ๋ก์ ํธ ์์ฑ TestNG class ์์ฑ ๋ฐฉ๋ฒ ์์ (0) | 2023.04.14 |
Selenium ์๋ํ ํ๊ฒฝ ์ค์ , maven TestNG ChromeDriver (0) | 2023.04.13 |