제출에러 수정하기!!!!!!!!!!!!(드디어 성공)

Yellta·2024년 8월 8일
0

Projects

목록 보기
5/6

OBJECT/SUBJECT:

제출이 되는 경우/ 되지 않는 경우로 제출의 결과가 나뉜다.

되는 경우. 되지 않는 경우가 존재하기 때문에 프로그램의 정확성을 높히기위해서 에러를 얼른 고쳐야한다

ANALYSIS:

1. submit button을 찾았지만 제대로 누르지 못한 경우

해당 경우가 이 문제의 키포인트 같았다. 실제로 잘 작동하던 때도 있었으니까 말이다.

1. submit버튼의 여부를 위해서 테스트 환경 구성하기

@SpringBootTest
@Import(TestConfiguration.class)
@Slf4j
public class LoadingAndEnterMethodTest {

    @Autowired
    MachineLoadingAndEnterZenput machineLoadingAndEnterZenput;

    @Autowired
    FoodLoadingAndEnterZenput foodLoadingAndEnterZenput;

    @Test
    @DisplayName("Machine Enter")
    public void machineLoading(){
        
        JSONObject machineMap = new JSONObject();
        machineMap.put("mgrname", "띤또뚠");

        JSONArray contents =new JSONArray();
        JSONObject tempMap = new JSONObject();

        tempMap.put("id","2");
        tempMap.put("name","온도계(탐침1)" );
        tempMap.put("temp","32");

        JSONObject tempMap4 = new JSONObject();
        tempMap4.put("id","54");
        tempMap4.put("name","온도계(탐침2)" );
        tempMap4.put("temp","31");

        JSONObject tempMap5 = new JSONObject();
        tempMap5.put("id","56");
        tempMap5.put("name","온도계(표면1)" );
        tempMap5.put("temp","33");


        JSONObject tempMap2 = new JSONObject();
        tempMap2.put("id","117");
        tempMap2.put("name","워크인프리저");
        tempMap2.put("temp","-3");

        JSONObject tempMap3 = new JSONObject();
        tempMap3.put("id","20");
        tempMap3.put("name","스페셜티프리저1");
        tempMap3.put("temp","-2");

        contents.put(tempMap);
        contents.put(tempMap4);
        contents.put(tempMap5);
        contents.put(tempMap2);
        contents.put(tempMap3);

        machineMap.put("customMachine", contents);

        machineMap.put("time","PM");

        log.info("map result = {}", machineMap.toString(2));

        try {
            Map<String, String> machine = machineLoadingAndEnterZenput.sendValueV2(machineMap.toString());
            log.info(machine.toString());
        } catch (Exception e) {
            log.info(e.toString());
        }
    }

}

실제로 매장에서 사용하는 사이트를 쓸 수 없기 때문에 테스트페이지로 진행을 수행했다.

그럼 Config.java파일에 있는 configuration이 아닌 Test를 위한 독자적인 bean관리가 필요했다.

따라서


@org.springframework.boot.test.context.TestConfiguration
@EnableJpaRepositories(basePackages = "burgerput.project.zenput.repository")

class TestConfiguration {
    @Bean
    public MachineLoadingAndEnterZenputV2T machineLoadingAndEnterZenput() {
        return new MachineLoadingAndEnterZenputV2T();
    }

    @Bean
    public FoodLoadingAndEnterZenputV2T foodLoadingAndEnterZenput() {
        return new FoodLoadingAndEnterZenputV2T();
    }


}

위처럼 LoadingAndZentput 테스트 파일을 빈으로 주입받는 TestConfiguration을 만들었다.

2. HTML파일 준비

Test HTML파일을 준비한다. 기존의 파일은 submit 버튼을 눌러도 아무것도 실행되지 않기 때문에 alert창을 띄워서 확인하도록 했다.

 <script>
        document.addEventListener("DOMContentLoaded", function() {
            var submitForm = document.getElementById("submit_form");
            if (submitForm) {
                submitForm.addEventListener("click", function() {
                    alert("Submit form clicked!");
                });
            }
        });
    </script>

html하단에 submit을 Alert창이 뜨도록 설정했다.

이렇게 말이다.

그럼 headless를 주고 해당 화면을 캡쳐하도록 확인해보자

    <div id="success_message" class="success-message" style="display: none;">성공</div>
    
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var submitForm = document.getElementById("submit_form");
            var successMessage = document.getElementById("success_message");
            if (submitForm) {
                submitForm.addEventListener("click", function() {
                    successMessage.style.display = 'block';
                });
            }
        });
    </script>

Alert창을 띄운뒤에 캡쳐가 되지 않아서 버튼을 누르면 성공이라고 나타나게 설정했다.

그리고 MachineLoadingAndZenputTest파일에서 드라이버 로딩 시간을 120초로 증가시키고 Thread.sleep으로 강제로 쉬던 부분은 제거했다.

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(120), Duration.ofMillis(500));
            JavascriptExecutor js = (JavascriptExecutor) driver;

            // JavaScript 로드 완료 대기
            wait.until(webDriver -> js.executeScript("return document.readyState").equals("complete"));
            log.info("enver Food and rest 3000");
            Thread.sleep(3000);
 private void enterValue(WebElement field, ArrayList<Map<String, String>> machineMap, Map<String,String> resultMap) {

        try {

            //extract vaild id field
            WebElement input = field.findElement(By.tagName("input"));

            String id = input.getAttribute("field_id");

            for (int i = 0; i < machineMap.size(); i++) {
                Map<String, String> customMap = machineMap.get(i);
                try {
                    if (id.equals(customMap.get("id"))) {

                        log.info("enter Map info {}", customMap);
                        input.sendKeys(customMap.get("temp"));
                        input.sendKeys(Keys.TAB);
//                        Thread.sleep(1000);
                        machineMap.remove(i);
                        break;
                    }
                } catch (NullPointerException e) {
                    log.info("error message ={}", e);
                    //do nothing
                } catch (ElementNotInteractableException e) {
                    log.info("ElementNotinteratable Excpetion error");
                    log.info(e.toString());

                    resultMap.put("result", "false");

                }
            }


        } catch (Exception e) {
            log.info("Error LoadFood={}", e.toString());
        }
    }

결과

Machine: 성공!!!

현재 Food는 파일이 없어서 테스트를 못한다. 하지만 Machine과 로직이 똑같다… ㅠ 근데 왜 테스트는 되고 왜 서버에 올리면 되지 않는 걸까?…

혹시나 하는 마음에!!…


            File screenshotAs = ((TakesScreenshot) driver).getScreenshotAs((OutputType.FILE));
            File file = new File("/home/ubuntu/burgerput/img/zenputMachine"+ LocalDate.now()+ LocalTime.now()+".png");
            FileUtils.copyFile(screenshotAs, file);

            WebElement submitForm = wait.until(ExpectedConditions.visibilityOfElementLocated((By.id("submit_form"))));
            submitForm.click();

            log.info("Machine button Clicked");
            log.info("quit the Driver ()");
            driver.quit();

기존에는 버튼을 누르고 바로 driver를 종료했었다. 그렇다면 시간을 조금 준 뒤에 종료하게 된다면 어떻게 될까? 그렇다 제출을 하고 시간을 줘보는 것이야!!!!!!!!!!!!!!!!!!!!

최종 결론

  1. 온도를 입력할 때 줬던 불필요한 Thread.sleep은 모두 지운다.
  2. driver 대기 시간을 120초로 넉넉하게 준다.
  3. 제출 버튼을 누른 뒤에 잠시 대기하도록 한다.(5초)
          WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(120), Duration.ofMillis(500));
            JavascriptExecutor js = (JavascriptExecutor) driver;

            // JavaScript 로드 완료 대기
            wait.until(webDriver -> js.executeScript("return document.readyState").equals("complete"));
...
          
          
           File screenshotAs = ((TakesScreenshot) driver).getScreenshotAs((OutputType.FILE));
            File file = new File("/home/ubuntu/burgerput/img/zenputMachine"+ LocalDate.now()+ LocalTime.now()+".png");
            FileUtils.copyFile(screenshotAs, file);

            WebElement submitForm = wait.until(ExpectedConditions.visibilityOfElementLocated((By.id("submit_form"))));
            submitForm.click();


            log.info("Machine button Clicked");
            log.info("rest 5000 and quit the Driver ()");
            Thread.sleep(5000);

enterValueV2 로직에 불필요한 Thread.sleep을 모두 제거했다.

그 후에 제출버튼을 클릭하고 5초 쉬도록 했다. 제출버튼을 클릭하고 그 다음 페이지의 정보가 나한테 없어서 지금은 이게 최선이다.

CONCLUSION:

원인 : 아직 시험해보지 않았지만!… 제출후 바로 driver를 닫았기 때문

셀레니움을 사용해서 웹 사이트에 값을 제출하고 드라이버를 종료하면 제출이 완료되지 않을 가능성이 있다. 제출 버튼을 클릭한 후 웹 사이트가 응답하기 전에 드라이버를 종료했기 때문이다.

제출 버튼을 클릭한 후 서버의 응답을 기다려야한다!!!

작업 :

  1. 온도를 입력할 때 줬던 불필요한 Thread.sleep은 모두 지운다.
  2. driver 대기 시간을 120초로 넉넉하게 준다.
  3. 제출 버튼을 누른 뒤에 잠시 대기하도록 한다.(5초)

결과 : 7월 28일 모두 정상작동 확인!!

REVIEW:

웹 서버에게 단순히 보내고 끝이 아니다. 응답을 기다려야한다!!!

언제나 요청-응답 쌍임을 잊지말자. 요청-응답 요청-응답

Seleinum라이브러리에서 요청을 바로 보낸후 driver를 닫아버리면 서버의 응답을 받아버리기 전에 닫히므로 요청이 제대로 수행되지 않는 경우가 있다.

profile
Yellta가 BE개발해요! 왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜 가 제일 중요하죠

0개의 댓글