init
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package com.eactive.apim.portal.apps;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DTOFieldUtils {
|
||||
public static List<String> getFieldNames(Class<?> dtoClass) {
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (Field field : dtoClass.getDeclaredFields()) {
|
||||
fieldNames.add(field.getName());
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
// Optional: Retrieve fields with specific annotations (e.g., @NotNull)
|
||||
public static List<String> getFieldNamesWithAnnotation(Class<?> dtoClass, Class annotationClass) {
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (Field field : dtoClass.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(annotationClass)) {
|
||||
fieldNames.add(field.getName());
|
||||
}
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
|
||||
import com.eactive.apim.portal.apps.user.controller.AccountController;
|
||||
import com.eactive.apim.portal.apps.user.dto.PasswordChangeRequestDTO;
|
||||
import com.eactive.apim.portal.apps.user.dto.PortalOrgDTO;
|
||||
import com.eactive.apim.portal.apps.user.service.PortalUserService;
|
||||
import com.eactive.apim.portal.common.user.PortalAuthenticatedUser;
|
||||
import com.eactive.apim.portal.common.util.SecurityUtil;
|
||||
import com.eactive.apim.portal.file.service.FileService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AccountControllerTest {
|
||||
|
||||
@Mock
|
||||
private Validator validator;
|
||||
|
||||
@Mock
|
||||
private PortalUserService userService;
|
||||
|
||||
@Mock
|
||||
private FileService fileService;
|
||||
|
||||
@InjectMocks
|
||||
private AccountController accountController;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(accountController).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testChangePassword() throws Exception {
|
||||
mockMvc.perform(get("/change_password.do"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("apps/main/myUpdatePw"))
|
||||
.andExpect(model().attributeExists("passwordChangeRequest"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatePassword() throws Exception {
|
||||
PasswordChangeRequestDTO dto = new PasswordChangeRequestDTO();
|
||||
dto.setOldPassword("old");
|
||||
dto.setNewPassword("new");
|
||||
dto.setNewPassword2("new");
|
||||
|
||||
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
|
||||
securityUtil.when(SecurityUtil::getCurrentLoginId).thenReturn("testUser");
|
||||
|
||||
// when(userService.findByLoginId("testUser")).thenReturn(true);
|
||||
|
||||
mockMvc.perform(post("/update_password.do")
|
||||
.flashAttr("passwordChangeRequest", dto))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("apps/main/myUpdatePw"))
|
||||
.andExpect(model().attributeExists("passwordChangeRequest"));
|
||||
|
||||
verify(validator).validate(any(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatePasswordWithErrors() throws Exception {
|
||||
PasswordChangeRequestDTO dto = new PasswordChangeRequestDTO();
|
||||
dto.setOldPassword("old");
|
||||
dto.setNewPassword("new");
|
||||
dto.setNewPassword2("different");
|
||||
|
||||
doAnswer(invocation -> {
|
||||
BindingResult bindingResult = invocation.getArgument(1);
|
||||
bindingResult.rejectValue("newPassword2", "error.password", "Passwords do not match");
|
||||
return null;
|
||||
}).when(validator).validate(any(), any(BindingResult.class));
|
||||
|
||||
mockMvc.perform(post("/update_password.do")
|
||||
.flashAttr("passwordChangeRequest", dto))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("apps/main/myUpdatePw"))
|
||||
.andExpect(model().attributeExists("errors"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMypage() {
|
||||
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
|
||||
PortalAuthenticatedUser user = new PortalAuthenticatedUser();
|
||||
securityUtil.when(SecurityUtil::getPortalAuthenticatedUser).thenReturn(user);
|
||||
|
||||
ModelAndView mav = accountController.mypage();
|
||||
|
||||
assertEquals("apps/main/myPageEnt", mav.getViewName());
|
||||
assertEquals(user, mav.getModel().get("user"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMyCompanyInfo() throws Exception {
|
||||
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
|
||||
securityUtil.when(SecurityUtil::getPortalAuthenticatedUser).thenReturn(new PortalAuthenticatedUser());
|
||||
|
||||
mockMvc.perform(get("/my_company_info.do"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("apps/main/myPageEntCompany"))
|
||||
.andExpect(model().attributeExists("user"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateCompanyInfo() throws Exception {
|
||||
PortalOrgDTO dto = new PortalOrgDTO();
|
||||
dto.setOrgName("Test Company");
|
||||
|
||||
try (MockedStatic<SecurityUtil> securityUtil = mockStatic(SecurityUtil.class)) {
|
||||
securityUtil.when(SecurityUtil::getCurrentLoginId).thenReturn("testUser");
|
||||
|
||||
mockMvc.perform(post("/update_my_company_info.do")
|
||||
.flashAttr("user", dto))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(redirectedUrl("/my_company_info.do"));
|
||||
|
||||
verify(validator).validate(eq(dto), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateCompanyInfoWithErrors() throws Exception {
|
||||
PortalOrgDTO dto = new PortalOrgDTO();
|
||||
|
||||
doAnswer(invocation -> {
|
||||
BindingResult bindingResult = invocation.getArgument(1);
|
||||
bindingResult.rejectValue("companyName", "error.companyName", "Company name is required");
|
||||
return null;
|
||||
}).when(validator).validate(any(), any(BindingResult.class));
|
||||
|
||||
mockMvc.perform(post("/update_my_company_info.do")
|
||||
.flashAttr("user", dto))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("apps/main/myPageEntCompany"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.openqa.selenium.*;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriverService;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public abstract class BaseWebTest {
|
||||
|
||||
public static final String HOST_URL = "http://localhost:8080";
|
||||
protected static final String TEST_FILES_DIR = "src/test/resources/test-files";
|
||||
protected static final int INPUT_DELAY_MILLIS = 1500; // 대기 시간
|
||||
|
||||
protected WebDriver driver;
|
||||
protected WebDriverWait wait;
|
||||
protected JavascriptExecutor js;
|
||||
protected Actions actions;
|
||||
|
||||
@BeforeAll
|
||||
public void setupClass() {
|
||||
WebDriverManager.chromedriver().setup();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setupTest() {
|
||||
ChromeOptions options = new ChromeOptions();
|
||||
options.addArguments("--no-sandbox");
|
||||
options.addArguments("--disable-dev-shm-usage");
|
||||
options.addArguments("--remote-allow-origins=*");
|
||||
|
||||
ChromeDriverService service = new ChromeDriverService.Builder()
|
||||
.usingAnyFreePort()
|
||||
.build();
|
||||
|
||||
driver = new ChromeDriver(service, options);
|
||||
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
|
||||
driver.manage().window().setSize(new Dimension(1280, 800)); // Set window size
|
||||
wait = new WebDriverWait(driver, Duration.ofSeconds(60)); // 대기 시간을 60초로 늘림
|
||||
js = (JavascriptExecutor) driver;
|
||||
actions = new Actions(driver);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
if (driver != null) {
|
||||
driver.quit();
|
||||
}
|
||||
}
|
||||
|
||||
protected void navigateTo(String url) {
|
||||
driver.get(url);
|
||||
}
|
||||
|
||||
|
||||
protected void triggerBlurEvent(By locator) {
|
||||
try {
|
||||
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(locator));
|
||||
// First try using JavaScript blur()
|
||||
try {
|
||||
js.executeScript("arguments[0].blur();", element);
|
||||
} catch (Exception jsException) {
|
||||
// If JavaScript fails, try simulating tab key press
|
||||
actions.moveToElement(element)
|
||||
.click()
|
||||
.sendKeys(Keys.TAB)
|
||||
.perform();
|
||||
}
|
||||
// Add a small delay to allow blur event handlers to execute
|
||||
Thread.sleep(500);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to trigger blur event: " + e.getMessage());
|
||||
throw new RuntimeException("Failed to trigger blur event", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void slowSendKeys(By by, String keys) throws InterruptedException {
|
||||
WebElement element = driver.findElement(by);
|
||||
for (char c : keys.toCharArray()) {
|
||||
element.sendKeys(String.valueOf(c));
|
||||
Thread.sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
private void createTestFilesDirectoryIfNotExists() {
|
||||
File directory = new File(TEST_FILES_DIR);
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private String getTestFilePath(String fileName) {
|
||||
Path resourcePath = Paths.get(TEST_FILES_DIR, fileName);
|
||||
return resourcePath.toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
protected void uploadFile(String inputId, String fileName) throws InterruptedException {
|
||||
try {
|
||||
String filePath = getTestFilePath(fileName);
|
||||
File file = new File(filePath);
|
||||
|
||||
if (!file.exists()) {
|
||||
System.err.println("Warning: Test file not found at " + filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for file input to be present
|
||||
WebElement fileInput = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(inputId)));
|
||||
|
||||
// Send the file path to the input
|
||||
fileInput.sendKeys(filePath);
|
||||
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to upload file: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected void clickElement(By by) {
|
||||
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(by));
|
||||
try {
|
||||
element.click();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
|
||||
} catch (Exception jsException) {
|
||||
new Actions(driver).moveToElement(element).click().perform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void slowClick(By by) throws InterruptedException {
|
||||
Thread.sleep(500);
|
||||
clickElement(by);
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
protected void checkCheckbox(By by) throws InterruptedException {
|
||||
WebElement checkbox = wait.until(ExpectedConditions.elementToBeClickable(by));
|
||||
if (!checkbox.isSelected()) {
|
||||
clickElement(by);
|
||||
}
|
||||
}
|
||||
|
||||
protected void scrollIntoView(WebElement element) {
|
||||
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
|
||||
}
|
||||
|
||||
protected boolean isButtonDisabled(By locator) {
|
||||
WebElement button = driver.findElement(locator);
|
||||
return !button.isEnabled() || button.getAttribute("disabled") != null;
|
||||
}
|
||||
|
||||
protected void handleEmailValidationAlert(String buttonId, String buttonName) {
|
||||
try {
|
||||
WebDriverWait alertWait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||
WebElement customAlert = alertWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("emailValidationPopup")));
|
||||
|
||||
// 커스텀 알림 메시지 출력
|
||||
//WebElement alertMessage = customAlert.findElement(By.id("customAlertMessage"));
|
||||
//System.out.println("Custom Alert message: " + alertMessage.getText());
|
||||
|
||||
// '확인' 버튼 클릭
|
||||
WebElement okButton = customAlert.findElement(By.id(buttonId));
|
||||
clickButtonSafely(okButton, buttonName);
|
||||
|
||||
// 알림창이 사라질 때까지 대기
|
||||
alertWait.until(ExpectedConditions.invisibilityOf(customAlert));
|
||||
} catch (TimeoutException e) {
|
||||
System.out.println("No custom alert appeared.");
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleAlert() {
|
||||
try {
|
||||
WebDriverWait alertWait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||
WebElement customAlert = alertWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("customAlert")));
|
||||
|
||||
// 커스텀 알림 메시지 출력
|
||||
WebElement alertMessage = customAlert.findElement(By.id("customAlertMessage"));
|
||||
System.out.println("Custom Alert message: " + alertMessage.getText());
|
||||
|
||||
// '확인' 버튼 클릭
|
||||
WebElement okButton = customAlert.findElement(By.id("customAlertOkButton"));
|
||||
clickButtonSafely(okButton, "알림 확인");
|
||||
|
||||
// 알림창이 사라질 때까지 대기
|
||||
alertWait.until(ExpectedConditions.invisibilityOf(customAlert));
|
||||
} catch (TimeoutException e) {
|
||||
System.out.println("No custom alert appeared.");
|
||||
}
|
||||
}
|
||||
|
||||
protected void clickButtonSafely(WebElement button, String buttonName) {
|
||||
try {
|
||||
// 버튼이 보이도록 스크롤
|
||||
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", button);
|
||||
Thread.sleep(500); // 스크롤 후 잠시 대기
|
||||
|
||||
// 먼저 일반적인 클릭 시도
|
||||
button.click();
|
||||
} catch (ElementClickInterceptedException | InterruptedException e) {
|
||||
System.out.println(buttonName + " 버튼 클릭 실패. JavaScript로 클릭을 시도합니다.");
|
||||
try {
|
||||
// JavaScript를 사용하여 클릭
|
||||
js.executeScript("arguments[0].click();", button);
|
||||
} catch (Exception jsException) {
|
||||
System.out.println(buttonName + " 버튼 JavaScript 클릭도 실패. Actions를 사용하여 클릭을 시도합니다.");
|
||||
// Actions를 사용하여 클릭
|
||||
actions.moveToElement(button).click().perform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertElementText(By locator, String expectedText) {
|
||||
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(locator));
|
||||
Assertions.assertEquals(expectedText, element.getText(), "Element text does not match expected value");
|
||||
}
|
||||
|
||||
protected void assertUrlContains(String expectedUrlPart) {
|
||||
wait.until(ExpectedConditions.urlContains(expectedUrlPart));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class PortalOrgRegistrationRetainTest extends BaseWebTest {
|
||||
|
||||
|
||||
public static final String HOST_URL = "http://localhost:8080";
|
||||
|
||||
private final String USER_ID_FILE = "user_id_counter.txt";
|
||||
|
||||
private static final String BUSINESS_LICENSE_FILE = "business-license.pptx";
|
||||
|
||||
@BeforeAll
|
||||
public void setupClass() {
|
||||
WebDriverManager.chromedriver().setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
if (driver != null) {
|
||||
driver.quit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignupScenarios() throws InterruptedException {
|
||||
navigateToRegistrationPage();
|
||||
fillRegistrationForm();
|
||||
}
|
||||
|
||||
public void navigateToRegistrationPage() throws InterruptedException {
|
||||
driver.get(HOST_URL + "/signup");
|
||||
|
||||
// '기관회원가입' 링크를 찾아 클릭
|
||||
WebElement orgSignupLink = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.xpath("//div[contains(@class, 'mb_group2')]/a/span[text()='법인회원가입']")));
|
||||
orgSignupLink.click();
|
||||
|
||||
// 새 URL로 이동했는지 확인
|
||||
wait.until(ExpectedConditions.urlToBe(HOST_URL + "/signup/portalOrg"));
|
||||
|
||||
// 페이지 로딩을 위한 추가 대기 시간
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
}
|
||||
|
||||
public void fillRegistrationForm() throws InterruptedException {
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 약관 동의
|
||||
WebElement agreeAll = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("agree_all")));
|
||||
scrollIntoView(agreeAll);
|
||||
checkCheckbox(By.id("agree_all"));
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 사업자 등록번호
|
||||
slowSendKeys(By.id("compRegNo1"), "527");
|
||||
slowSendKeys(By.id("compRegNo2"), "88");
|
||||
slowSendKeys(By.id("compRegNo3"), "00686");
|
||||
handleAlert();
|
||||
Thread.sleep(3000);
|
||||
|
||||
// 법인 등록번호
|
||||
slowSendKeys(By.id("corpRegNo1"), "131111");
|
||||
slowSendKeys(By.id("corpRegNo2"), "0478337");
|
||||
handleAlert();
|
||||
Thread.sleep(3000);
|
||||
// 기관명
|
||||
slowSendKeys(By.id("orgName"), "카카오페이");
|
||||
|
||||
// 대표자 성명
|
||||
slowSendKeys(By.id("ceoName"), "신원근");
|
||||
|
||||
// 사업장 소재지 주소
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("ceoName")));
|
||||
scrollIntoView(field);
|
||||
|
||||
slowSendKeys(By.id("orgAddr"), "경기도 성남시 분당구 판교역로 166, 비동 15층(백현동)");
|
||||
|
||||
// 업태
|
||||
slowSendKeys(By.id("orgSectors"), "금융 지원 서비스업");
|
||||
|
||||
// 종목
|
||||
slowSendKeys(By.id("orgIndustryType"), "전자상거래 소매업");
|
||||
|
||||
// 회사 전화번호
|
||||
closeDropdownIfOpen("orgAreaCode");
|
||||
selectCustomOption("orgAreaCode", "없음");
|
||||
slowSendKeys(By.id("orgPhoneNumber1"), "1644");
|
||||
slowSendKeys(By.id("orgPhoneNumber2"), "7405");
|
||||
|
||||
// 서비스명
|
||||
slowSendKeys(By.id("serviceName"), "카카오페이");
|
||||
|
||||
// 고객센터 전화번호
|
||||
selectCustomOption("scAreaCode", "없음");
|
||||
slowSendKeys(By.id("scPhoneNumber1"), "1644");
|
||||
slowSendKeys(By.id("scPhoneNumber2"), "7405");
|
||||
|
||||
// 여기에 파일 업로드 로직 추가 (사업자 등록증)
|
||||
uploadFile("files", BUSINESS_LICENSE_FILE);
|
||||
|
||||
// 기본 관리자 정보
|
||||
slowSendKeys(By.id("userId"), "user");
|
||||
slowSendKeys(By.id("domain"), "eee.com");
|
||||
WebElement checkEmailButton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn_check .btn_check_email")));
|
||||
clickButtonSafely(checkEmailButton, "이메일 중복체크");
|
||||
handleEmailValidationAlert("emailConvertButton", "이메일 유지");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
slowSendKeys(By.id("passwordConfirmIndividual"), "bravo135!");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS); //추가 대기 시간
|
||||
|
||||
// 가입신청 버튼 클릭 (실제 제출은 하지 않습니다)
|
||||
WebElement submitButton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn_register")));
|
||||
submitButton.click(); // 주석 처리하여 실제 제출은 하지 않습니다
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
|
||||
private void fillFieldAndHandleAlert(String fieldName, String value) throws InterruptedException {
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(fieldName)));
|
||||
field.clear();
|
||||
field.sendKeys(value);
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
handleAlert();
|
||||
}
|
||||
|
||||
|
||||
private void verifyPhoneNumber() throws InterruptedException {
|
||||
|
||||
// 인증번호 받기 버튼 찾기 (여러 방법 시도)
|
||||
WebElement getAuthButton = null;
|
||||
try {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector(".btn_check .common_btn_type_2.cbt.btn_auth")));
|
||||
} catch (TimeoutException e) {
|
||||
try {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.xpath("//a[contains(@class, 'btn_auth') and .//span[text()='인증번호 받기']]")));
|
||||
} catch (TimeoutException e2) {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("[hx-post*='/request_register_auth.do']")));
|
||||
}
|
||||
}
|
||||
|
||||
if (getAuthButton == null) {
|
||||
throw new NoSuchElementException("인증번호 받기 버튼을 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
// 버튼 클릭
|
||||
clickButtonSafely(getAuthButton, "인증번호 받기");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 알림창 처리
|
||||
handleAlert();
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 인증번호 입력 컨테이너가 나타날 때까지 대기
|
||||
WebElement authNumberContainer = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("authNumberContainer")));
|
||||
|
||||
// 인증번호 입력
|
||||
slowSendKeys(By.id("authNumber"), "123456");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 인증번호 확인 버튼 클릭
|
||||
WebElement verifyButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector(".btn_verify_auth")));
|
||||
clickButtonSafely(verifyButton, "인증번호 확인");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 추가적인 알림창이 있다면 처리
|
||||
handleAlert();
|
||||
}
|
||||
|
||||
|
||||
private void fillSplitFieldByName(String fieldName, String[] values) throws InterruptedException {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.name(fieldName + (i + 1))));
|
||||
field.clear();
|
||||
field.sendKeys(values[i]);
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void selectCustomOption(String selectId, String optionValue) throws InterruptedException {
|
||||
try {
|
||||
// Wait for and click the select_selected div to open dropdown
|
||||
WebElement selectSelected = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("#" + selectId + " .select_selected")));
|
||||
|
||||
// Wait for and verify the element doesn't have 'active' class before clicking
|
||||
wait.until(ExpectedConditions.not(
|
||||
ExpectedConditions.attributeContains(selectSelected, "class", "active")));
|
||||
|
||||
actions.moveToElement(selectSelected).click().perform();
|
||||
|
||||
// Wait for the dropdown to become visible by checking both conditions:
|
||||
// 1. select_selected should have 'active' class
|
||||
// 2. common_selecttype should not have 'select_hide' class
|
||||
wait.until(ExpectedConditions.attributeContains(selectSelected, "class", "active"));
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype:not(.select_hide)")));
|
||||
|
||||
// Find and click the option
|
||||
WebElement option = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype li")));
|
||||
actions.moveToElement(option).click().perform();
|
||||
|
||||
// After clicking, verify:
|
||||
// 1. The dropdown is hidden again (select_hide class is present)
|
||||
// 2. select_selected no longer has active class
|
||||
// 3. The selected text is updated
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype.select_hide")));
|
||||
wait.until(ExpectedConditions.not(
|
||||
ExpectedConditions.attributeContains(selectSelected, "class", "active")));
|
||||
wait.until(ExpectedConditions.textToBe(
|
||||
By.cssSelector("#" + selectId + " .select_selected"), optionValue));
|
||||
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
} catch (TimeoutException e) {
|
||||
throw new RuntimeException("Failed to select option '" + optionValue +
|
||||
"' from custom select '" + selectId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method to check if dropdown is open
|
||||
private boolean isDropdownOpen(String selectId) {
|
||||
try {
|
||||
WebElement selectSelected = driver.findElement(By.cssSelector("#" + selectId + " .select_selected"));
|
||||
WebElement selectItems = driver.findElement(By.cssSelector("#" + selectId + " .common_selecttype"));
|
||||
|
||||
return selectSelected.getAttribute("class").contains("active") &&
|
||||
!selectItems.getAttribute("class").contains("select_hide");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method to get currently selected value
|
||||
private String getSelectedValue(String selectId) {
|
||||
return driver.findElement(By.cssSelector("#" + selectId + " .select_selected"))
|
||||
.getText();
|
||||
}
|
||||
|
||||
// Utility method to close dropdown if open
|
||||
private void closeDropdownIfOpen(String selectId) {
|
||||
if (isDropdownOpen(selectId)) {
|
||||
actions.click(driver.findElement(By.cssSelector("body"))).perform();
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype.select_hide")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String generateUserId() {
|
||||
int currentId = readUserIdFromFile();
|
||||
int newId = currentId + 1;
|
||||
writeUserIdToFile(newId);
|
||||
return String.format("user%03d", newId);
|
||||
}
|
||||
|
||||
private int readUserIdFromFile() {
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(USER_ID_FILE))) {
|
||||
String line = reader.readLine();
|
||||
return line != null ? Integer.parseInt(line.trim()) : 0;
|
||||
} catch (IOException e) {
|
||||
System.out.println("파일을 읽는 중 오류가 발생했습니다. 새로운 ID를 1부터 시작합니다.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeUserIdToFile(int id) {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(USER_ID_FILE))) {
|
||||
writer.write(String.valueOf(id));
|
||||
} catch (IOException e) {
|
||||
System.out.println("파일에 ID를 쓰는 중 오류가 발생했습니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class PortalOrgRegistrationTest extends BaseWebTest {
|
||||
|
||||
public static final int INPUT_DELAY_MILLIS = 1500; // 대기 시간을 2000ms로 늘림
|
||||
private static final String BUSINESS_LICENSE_FILE = "business-license.pptx";
|
||||
private final String USER_ID_FILE = "user_id_counter.txt";
|
||||
|
||||
@BeforeAll
|
||||
public void setupClass() {
|
||||
WebDriverManager.chromedriver().setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
if (driver != null) {
|
||||
driver.quit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignupScenarios() throws InterruptedException {
|
||||
navigateToRegistrationPage();
|
||||
fillRegistrationForm();
|
||||
}
|
||||
|
||||
public void navigateToRegistrationPage() throws InterruptedException {
|
||||
driver.get(HOST_URL + "/signup");
|
||||
|
||||
// '기관회원가입' 링크를 찾아 클릭
|
||||
WebElement orgSignupLink = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.xpath("//div[contains(@class, 'mb_group2')]/a/span[text()='법인회원가입']")));
|
||||
orgSignupLink.click();
|
||||
|
||||
// 새 URL로 이동했는지 확인
|
||||
wait.until(ExpectedConditions.urlToBe(HOST_URL + "/signup/portalOrg"));
|
||||
|
||||
// 페이지 로딩을 위한 추가 대기 시간
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
}
|
||||
|
||||
public void fillRegistrationForm() throws InterruptedException {
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 약관 동의
|
||||
WebElement agreeAll = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("agree_all")));
|
||||
scrollIntoView(agreeAll);
|
||||
checkCheckbox(By.id("agree_all"));
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 사업자 등록번호
|
||||
slowSendKeys(By.id("compRegNo1"), "527");
|
||||
slowSendKeys(By.id("compRegNo2"), "88");
|
||||
slowSendKeys(By.id("compRegNo3"), "00686");
|
||||
handleAlert();
|
||||
Thread.sleep(3000);
|
||||
|
||||
// 법인 등록번호
|
||||
slowSendKeys(By.id("corpRegNo1"), "131111");
|
||||
slowSendKeys(By.id("corpRegNo2"), "0478337");
|
||||
handleAlert();
|
||||
Thread.sleep(3000);
|
||||
// 기관명
|
||||
slowSendKeys(By.id("orgName"), "카카오페이");
|
||||
|
||||
// 대표자 성명
|
||||
slowSendKeys(By.id("ceoName"), "신원근");
|
||||
|
||||
// 사업장 소재지 주소
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("orgAddr")));
|
||||
scrollIntoView(field);
|
||||
|
||||
slowSendKeys(By.id("orgAddr"), "경기도 성남시 분당구 판교역로 166, 비동 15층(백현동)");
|
||||
|
||||
// 업태
|
||||
slowSendKeys(By.id("orgSectors"), "금융 지원 서비스업");
|
||||
|
||||
// 종목
|
||||
slowSendKeys(By.id("orgIndustryType"), "전자상거래 소매업");
|
||||
|
||||
// 회사 전화번호
|
||||
closeDropdownIfOpen("orgAreaCode");
|
||||
selectCustomOption("orgAreaCode", "없음");
|
||||
slowSendKeys(By.id("orgPhoneNumber1"), "1644");
|
||||
slowSendKeys(By.id("orgPhoneNumber2"), "7405");
|
||||
|
||||
// 서비스명
|
||||
slowSendKeys(By.id("serviceName"), "카카오페이");
|
||||
|
||||
// 고객센터 전화번호
|
||||
selectCustomOption("scAreaCode", "없음");
|
||||
slowSendKeys(By.id("scPhoneNumber1"), "1644");
|
||||
slowSendKeys(By.id("scPhoneNumber2"), "7405");
|
||||
|
||||
// 여기에 파일 업로드 로직 추가 (사업자 등록증)
|
||||
uploadFile("files", BUSINESS_LICENSE_FILE);
|
||||
|
||||
// 기본 관리자 정보
|
||||
fillField("userId", generateUserId());
|
||||
fillField("domain", "kakao.com");
|
||||
WebElement checkEmailButton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn_check .btn_check_email")));
|
||||
clickButtonSafely(checkEmailButton, "이메일 중복체크");
|
||||
handleAlert();
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
slowSendKeys(By.id("userName"), "홍길동");
|
||||
|
||||
// 휴대폰 번호
|
||||
selectCustomOption("phoneMobile", "010");
|
||||
slowSendKeys(By.id("cellPhone1"), "1234");
|
||||
slowSendKeys(By.id("cellPhone2"), "1644");
|
||||
|
||||
verifyPhoneNumber();
|
||||
|
||||
slowSendKeys(By.id("password"), "bravo135!");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS); //추가 대기 시간
|
||||
|
||||
slowSendKeys(By.id("password2"), "bravo135!");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS); //추가 대기 시간
|
||||
|
||||
triggerBlurEvent(By.id("password2"));
|
||||
|
||||
Thread.sleep(INPUT_DELAY_MILLIS); //추가 대기 시간
|
||||
|
||||
// 가입신청 버튼 클릭
|
||||
WebElement submitButton2 = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn_register")));
|
||||
submitButton2.click(); // 주석 처리하여 실제 제출은 하지 않습니다
|
||||
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
|
||||
private void fillFieldAndHandleAlert(String fieldName, String value) throws InterruptedException {
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(fieldName)));
|
||||
field.clear();
|
||||
field.sendKeys(value);
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
handleAlert();
|
||||
}
|
||||
|
||||
|
||||
private void verifyPhoneNumber() throws InterruptedException {
|
||||
|
||||
// 인증번호 받기 버튼 찾기 (여러 방법 시도)
|
||||
WebElement getAuthButton = null;
|
||||
try {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector(".btn_check .common_btn_type_2.cbt.btn_auth")));
|
||||
} catch (TimeoutException e) {
|
||||
try {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.xpath("//a[contains(@class, 'btn_auth') and .//span[text()='인증번호 받기']]")));
|
||||
} catch (TimeoutException e2) {
|
||||
getAuthButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("[hx-post*='/request_register_auth.do']")));
|
||||
}
|
||||
}
|
||||
|
||||
if (getAuthButton == null) {
|
||||
throw new NoSuchElementException("인증번호 받기 버튼을 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
// 버튼 클릭
|
||||
clickButtonSafely(getAuthButton, "인증번호 받기");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 알림창 처리
|
||||
handleAlert();
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 인증번호 입력 컨테이너가 나타날 때까지 대기
|
||||
WebElement authNumberContainer = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("authNumberContainer")));
|
||||
|
||||
// 인증번호 입력
|
||||
slowSendKeys(By.id("authNumber"), "123456");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 인증번호 확인 버튼 클릭
|
||||
WebElement verifyButton = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector(".btn_verify_auth")));
|
||||
clickButtonSafely(verifyButton, "인증번호 확인");
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
|
||||
// 추가적인 알림창이 있다면 처리
|
||||
handleAlert();
|
||||
}
|
||||
|
||||
|
||||
private void fillSplitFieldByName(String fieldName, String[] values) throws InterruptedException {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.name(fieldName + (i + 1))));
|
||||
field.clear();
|
||||
field.sendKeys(values[i]);
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fillField(String fieldName, String value) throws InterruptedException {
|
||||
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(fieldName)));
|
||||
field.clear();
|
||||
field.sendKeys(value);
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
}
|
||||
|
||||
private void selectCustomOption(String selectId, String optionValue) throws InterruptedException {
|
||||
try {
|
||||
// Wait for and click the select_selected div to open dropdown
|
||||
WebElement selectSelected = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("#" + selectId + " .select_selected")));
|
||||
|
||||
// Wait for and verify the element doesn't have 'active' class before clicking
|
||||
wait.until(ExpectedConditions.not(
|
||||
ExpectedConditions.attributeContains(selectSelected, "class", "active")));
|
||||
|
||||
actions.moveToElement(selectSelected).click().perform();
|
||||
|
||||
// Wait for the dropdown to become visible by checking both conditions:
|
||||
// 1. select_selected should have 'active' class
|
||||
// 2. common_selecttype should not have 'select_hide' class
|
||||
wait.until(ExpectedConditions.attributeContains(selectSelected, "class", "active"));
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype:not(.select_hide)")));
|
||||
|
||||
// Find and click the option
|
||||
WebElement option = wait.until(ExpectedConditions.elementToBeClickable(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype li")));
|
||||
actions.moveToElement(option).click().perform();
|
||||
|
||||
// After clicking, verify:
|
||||
// 1. The dropdown is hidden again (select_hide class is present)
|
||||
// 2. select_selected no longer has active class
|
||||
// 3. The selected text is updated
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype.select_hide")));
|
||||
wait.until(ExpectedConditions.not(
|
||||
ExpectedConditions.attributeContains(selectSelected, "class", "active")));
|
||||
wait.until(ExpectedConditions.textToBe(
|
||||
By.cssSelector("#" + selectId + " .select_selected"), optionValue));
|
||||
|
||||
Thread.sleep(INPUT_DELAY_MILLIS);
|
||||
} catch (TimeoutException e) {
|
||||
throw new RuntimeException("Failed to select option '" + optionValue +
|
||||
"' from custom select '" + selectId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method to check if dropdown is open
|
||||
private boolean isDropdownOpen(String selectId) {
|
||||
try {
|
||||
WebElement selectSelected = driver.findElement(By.cssSelector("#" + selectId + " .select_selected"));
|
||||
WebElement selectItems = driver.findElement(By.cssSelector("#" + selectId + " .common_selecttype"));
|
||||
|
||||
return selectSelected.getAttribute("class").contains("active") &&
|
||||
!selectItems.getAttribute("class").contains("select_hide");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method to get currently selected value
|
||||
private String getSelectedValue(String selectId) {
|
||||
return driver.findElement(By.cssSelector("#" + selectId + " .select_selected"))
|
||||
.getText();
|
||||
}
|
||||
|
||||
// Utility method to close dropdown if open
|
||||
private void closeDropdownIfOpen(String selectId) {
|
||||
if (isDropdownOpen(selectId)) {
|
||||
actions.click(driver.findElement(By.cssSelector("body"))).perform();
|
||||
wait.until(ExpectedConditions.presenceOfElementLocated(
|
||||
By.cssSelector("#" + selectId + " .common_selecttype.select_hide")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String generateUserId() {
|
||||
int currentId = readUserIdFromFile();
|
||||
int newId = currentId + 1;
|
||||
writeUserIdToFile(newId);
|
||||
return String.format("user%03d", newId);
|
||||
}
|
||||
|
||||
private int readUserIdFromFile() {
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(USER_ID_FILE))) {
|
||||
String line = reader.readLine();
|
||||
return line != null ? Integer.parseInt(line.trim()) : 0;
|
||||
} catch (IOException e) {
|
||||
System.out.println("파일을 읽는 중 오류가 발생했습니다. 새로운 ID를 1부터 시작합니다.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeUserIdToFile(int id) {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(USER_ID_FILE))) {
|
||||
writer.write(String.valueOf(id));
|
||||
} catch (IOException e) {
|
||||
System.out.println("파일에 ID를 쓰는 중 오류가 발생했습니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
|
||||
import com.eactive.apim.portal.apps.DTOFieldUtils;
|
||||
import com.eactive.apim.portal.apps.user.dto.PortalUserRegistrationDTO;
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class PortalUserRegisterFieldTest extends BaseWebTest{
|
||||
|
||||
|
||||
|
||||
@BeforeAll
|
||||
public void setupClass() {
|
||||
WebDriverManager.chromedriver().setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
if (driver != null) {
|
||||
driver.quit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForm() {
|
||||
|
||||
String pageUrl = HOST_URL + "/signup/portalUser";
|
||||
Class<?> dtoClass = PortalUserRegistrationDTO.class;
|
||||
driver.get(pageUrl);
|
||||
|
||||
List<String> expectedFields = DTOFieldUtils.getFieldNames(dtoClass);
|
||||
|
||||
for (String fieldName : expectedFields) {
|
||||
List<WebElement> elements = driver.findElements(By.name(fieldName));
|
||||
assertTrue(elements.size() > 0, "Field '" + fieldName + "' is missing on the page");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import com.eactive.apim.portal.PortalApplication;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.http.Cookie;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@SpringBootTest(classes = PortalApplication.class)
|
||||
@ActiveProfiles({"dev", "unittest"})
|
||||
@AutoConfigureMockMvc
|
||||
class SignupFileTest {
|
||||
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
|
||||
try {
|
||||
|
||||
byte[] fileContent = "test file content".getBytes();
|
||||
MockMultipartFile mockFile = new MockMultipartFile("files", "test.txt", "text/plain", fileContent);
|
||||
|
||||
String csrfToken = Objects.requireNonNull(mockMvc.perform(get("/login"))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getCookie("XSRF-TOKEN")).getValue();
|
||||
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
// loginCsrf("hyunsp@gmail.com", "vhxkf123", session, csrfToken);
|
||||
|
||||
// Call the endpoint and get the response
|
||||
mockMvc.perform(
|
||||
multipart("/signup/portalOrg")
|
||||
.file(mockFile)
|
||||
.param("termsOfUse", "on")
|
||||
.param("privacyPolicy", "on")
|
||||
// .param("nttSj", "Article File Test")
|
||||
// .param("contents", "<p>wefwef</p><p>fwefwef</p><p>wefwef</p><p><br></p><script>\n" +
|
||||
// " alert('13');\n" +
|
||||
// " </script>")
|
||||
.session(session)
|
||||
.header("X-XSRF-TOKEN", csrfToken)
|
||||
.cookie(new Cookie("XSRF-TOKEN", csrfToken))
|
||||
)
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
// .andReturn();
|
||||
|
||||
// Verify the response
|
||||
// String response = result.getResponse().getContentAsString();
|
||||
// assertEquals("File uploaded successfully", response);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MockHttpServletResponse loginCsrf(String username, String password, MockHttpSession session, String csrfToken) throws Exception {
|
||||
//
|
||||
// ResultActions result = mockMvc.perform(post("/actionLogin.do")
|
||||
// .session(session)
|
||||
// .param("id", username)
|
||||
// .param("password", password)
|
||||
// .header("X-XSRF-TOKEN", csrfToken)
|
||||
// .cookie(new Cookie("XSRF-TOKEN", csrfToken)))
|
||||
// .andExpect(status().is3xxRedirection());
|
||||
//
|
||||
// return result.andReturn().getResponse();
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.eactive.apim.portal.apps.user;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
class SignupPageTest extends BaseWebTest {
|
||||
|
||||
private final String USER_ID_FILE = "user_id_counter.txt";
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> testSignupScenarios() throws IOException {
|
||||
Path csvPath = Paths.get("src", "test", "resources", "signup_test_cases.csv");
|
||||
return Files.lines(csvPath)
|
||||
.skip(1)
|
||||
.filter(s -> !s.startsWith("#"))// Skip header
|
||||
.map(line -> line.split(","))
|
||||
.map(data -> DynamicTest.dynamicTest("Test: " + data[0], () -> {
|
||||
runTest(data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||
}));
|
||||
}
|
||||
|
||||
private void runTest(String email, String phone, String verificationCode,
|
||||
String name, String password, String confirmPassword, String expectedResult) throws InterruptedException {
|
||||
navigateTo("http://devportal.elink365.net/join.do");
|
||||
Thread.sleep(1000);
|
||||
|
||||
WebElement allCheckbox = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("all")));
|
||||
scrollIntoView(allCheckbox);
|
||||
checkCheckbox(By.id("all"));
|
||||
Thread.sleep(1000);
|
||||
|
||||
WebElement registerButton = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("btn_register")));
|
||||
scrollIntoView(registerButton);
|
||||
slowClick(By.className("btn_register"));
|
||||
Thread.sleep(3000);
|
||||
|
||||
slowSendKeys(By.id("userId"), email);
|
||||
slowSendKeys(By.id("cellPhone"), phone);
|
||||
slowClick(By.className("btn_auth"));
|
||||
|
||||
handleAlert();
|
||||
|
||||
slowSendKeys(By.id("authNumber"), verificationCode);
|
||||
slowSendKeys(By.id("username"), name);
|
||||
slowSendKeys(By.id("password"), password);
|
||||
slowSendKeys(By.id("password2"), confirmPassword);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
boolean isButtonEnabled = !isButtonDisabled(By.className("btn_register"));
|
||||
|
||||
if (isButtonEnabled) {
|
||||
slowClick(By.className("btn_register"));
|
||||
|
||||
if ("회원 등록 완료".equals(expectedResult)) {
|
||||
assertUrlContains("/user_register.do");
|
||||
assertElementText(By.xpath("//h3[contains(text(), '회원 등록 완료')]"), "회원 등록 완료");
|
||||
} else {
|
||||
String result = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("validationUsernameInvalidFeedback"))).getText();
|
||||
Assertions.assertTrue(result.contains(expectedResult),
|
||||
"Expected result '" + expectedResult + "' not found in actual result: " + result);
|
||||
}
|
||||
} else {
|
||||
if ("Button Disabled".equals(expectedResult)) {
|
||||
Assertions.assertFalse(isButtonEnabled, "Form is invalid as expected and the button is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
점검항목,이메일,휴대전화,인증번호,신청자명,비밀번호,비밀번호확인,예상결과
|
||||
이메일 형식 확인,invalid_email,01012345678,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
이메일 중복 체크,hyunsp@gmail.com,01012345678,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
휴대전화 형식 확인,test_user2@example.com,0101234567,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
#휴대전화 중복 체크,test_user3@example.com,01012345678,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
인증번호 유효성,test_user4@example.com,01012345678,12345,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
신청자명 유효성,test_user5@example.com,01012345678,123456,홍길동!@#,Strong@Password1,Strong@Password1,Button Disabled
|
||||
비밀번호 복잡도,test_user6@example.com,01012345678,123456,홍길동,weak,weak,Button Disabled
|
||||
비밀번호 확인 일치,test_user7@example.com,01012345678,123456,홍길동,Strong@Password1,DifferentPassword,Button Disabled
|
||||
필수 필드 - 이메일,,01012345678,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
#필수 필드 - 휴대전화,test_user8@example.com,,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
필수 필드 - 인증번호,test_user9@example.com,01012345678,,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
#필수 필드 - 신청자명,test_user10@example.com,01012345678,123456,,Strong@Password1,Strong@Password1,Button Disabled
|
||||
필수 필드 - 비밀번호,test_user11@example.com,01012345678,123456,홍길동,,Strong@Password1,Button Disabled
|
||||
필수 필드 - 비밀번호 확인,test_user12@example.com,01012345678,123456,홍길동,Strong@Password1,,Button Disabled
|
||||
#유효한 데이터 - 정상 가입,valid_user@example.com,01087654321,123456,김철수,Secure135!@#,Secure135!@#,회원 등록 완료
|
||||
|
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
점검항목,이메일,휴대전화,인증번호,신청자명,비밀번호,비밀번호확인,예상결과
|
||||
이메일 형식 확인,invalid_email,01012345678,123456,홍길동,Strong@Password1,Strong@Password1,Button Disabled
|
||||
|
Reference in New Issue
Block a user