반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

지난 번 Selenium 관련 글에서 두개의 웹 어플리케이션에서 진행되는 flow를 하나의 테스트 케이스로 만드는 방법을 살펴 봤습니다.


아래와 같이 Selenium WebDriver의 Suite xml 파일에 <test> 라는 태그를 사용해서 진행할 수 있는 방법을 정리해 뒀었습니다.



<suite name="suite 이름">

     <listeners>
        <listener class-name=".........." />
    </listeners>
    <!-- GLOBAL PARAMETERS -->
    <parameter name="waitTime" value="40" />
    <parameter name="thinkTime" value="2" />

    <parameter name="app_url" value="웹 어플리케이션 URL" />
    <parameter name="username" value="아이디" />
    <parameter name="password" value="비밀번호" />
   
   
    <test verbose="10" name="이름 1" annotations="JDK" preserve-order="true">
        <classes>
            <class name="실행할 클래스 1" />
            <class name="실행할 클래스 2" />
            <class name="실행할 클래스 3" />
        </classes>
    </test>
   
    <test verbose="10" name="이름 2" annotations="JDK" preserve-order="true">
        <parameter name="browser" value="ie" />
        <parameter name="app_url1" value="웹 앱 URL 2" />
        <parameter name="username" value="아이디"" />
        <parameter name="password" value="비밀번호" />
       
        <classes>
            <class name="실행할 클래스 1" />
            <class name="실행할 클래스 2" />           
            <class name="실행할 클래스 3" />
        </classes>
    </test>
</suite>

첫번째 <test> 에서 사용하는 것은 일반 유저가 사용하는 웹 어플리케이션 이고 두번째 <test> 에서 사용하는 웹 어플리케이션은 관리자가 사용하는 것일 수 있는데요.


이 때 유저가 입력한 정보가 관리자 모드에서 제대로 표현 되는 지 여부를 테스트 해야 될 때가 있습니다.


예를 들어 첫번째 <test> 의 '실행할 클래스 3' 에서 유저가 물건을 주문했고 그 주문 번호가 1111111 일 경우.

두번째 <test> 에서는 이 주문번호가 제대로 입력이 됐는지. 그리고 그 주문번호에 따른 정보들이 제대로 들어가 있는지를 테스트 해야 될 수 있습니다.


이럴 경우 유저가 입력한 정보를 관리자모드에서 확인하도록 하는 방법은 여러 방법이 있겠습니다.


DB를 사용해서 정보를 가져와서 웹 페이지의 정보를 비교할 수 있겠고. 아니면 유저가 정보를 입력할 때 text나 다른 physical 한 파일 형태로 저장하고 관리자 모드에서 그 파일 안의 정보를 가져와서 테스트를 할 수 도 있구요.


그런데 단지 주문 번호 하나만 테스트를 해야 되는데 이렇게 DB 연결이나 물리적인 파일형태로 데이터를 저장하고 가져오는 것은 너무 복잡한 해결방법이 될 겁니다.


이 경우에는 User 모드에서 변수를 public static으로 저장하고 관리자 모드에서 그 정보를 가져와서 사용할 수 있습니다. (이것은 Selenium Webdriver에 대한 정보라기 보다는 자바 기초 정보입니다.)



예를 들어 위 코드내의 첫번째 <text>에 있는 '실행할 클래스 3' 에 아래와 같이 선언된 변수가 있습니다.


public static String orderNumber = null;

public static String userName = null;


그리고 유저가 이 정보를 입력하는 테스트 케이스에서 아래와 같이 이 변수에 그 정보를 담습니다.


@Test(alwaysRun = true)

public void inputOrderNumber() {

orderNumber = InputForm.getOrderNumber();

userName = InputForm.getUsername();

}


이 정보를 두번째 <test> 의 '실행할 클래스 3'에서 가져와서 해당 관리자모드 웹 페이지에 표시된 정보와 비교롤 합니다.


public static String orderNumber = null;

public static String userName = null;


@Test(alwaysRun = true)

public void checkOrderNumber() {

orderNumber = inputForm.orderNumber; (inputForm 은 첫번째 <test>의 '실행할 클래스3' 의 클래스 명)

}


오늘은 자바 기초 문법을 하나 정리 했네요.

반응형


반응형

ERP 웹 작업을 하다보면 일반 유저가 어떤 정보를 입력하고 관리자가 그 입력한 정보를 처리하는 프로세스들이 있습니다.


이 때 일반 유저가 입력할 때 사용하는 웹사이트와 관리자가 사용하는 웹사이트 즉 어플리케이션이 서로 다른 경우가 있습니다.


제가 참여하는 프로젝트에도 이런 경우가 있는데요.

거기에다가 일반 유저가 사용하는 웹어플리케이션은 아무 브라우저에서나 작동이 되는데 관리자가 사용하는 웹어플리케이션은 IE에서만 제대로 작동 됩니다.


그런데 테스트 케이스는 유저가 로그인해서 입력 완료하고 다시 관리자가 이를 처리하는 것 까지로 돼 있습니다.


이럴 경우 한개의 suite 에서 이 모든 일들을 처리할 수 있도록 해야 되는데요.


그럴 경우 아래와 같이 하면 됩니다.



<suite name="suite 이름">

     <listeners>
        <listener class-name=".........." />
    </listeners>
    <!-- GLOBAL PARAMETERS -->
    <parameter name="waitTime" value="40" />
    <parameter name="thinkTime" value="2" />

    <parameter name="app_url" value="웹 어플리케이션 URL" />
    <parameter name="username" value="아이디" />
    <parameter name="password" value="비밀번호" />
   
   
    <test verbose="10" name="이름 1" annotations="JDK" preserve-order="true">
        <classes>
            <class name="실행할 클래스 1" />
            <class name="실행할 클래스 2" />
            <class name="실행할 클래스 3" />
        </classes>
    </test>
   
    <test verbose="10" name="이름 2" annotations="JDK" preserve-order="true">
        <parameter name="browser" value="ie" />
        <parameter name="app_url1" value="웹 앱 URL 2" />
        <parameter name="username" value="아이디"" />
        <parameter name="password" value="비밀번호" />
       
        <classes>
            <class name="실행할 클래스 1" />
            <class name="실행할 클래스 2" />           
            <class name="실행할 클래스 3" />
        </classes>
    </test>
</suite>


이 테스트 suite 은 <suite>로 시작해서 </suite>으로 끝납니다.

listener를 작동해야 할 필요가 있으면 <listeners> 태그 안에 선언 합니다.


그 다음에 Parameter들을 선언하는 부분이 있습니다.

웹 URL이나 아이디 비밀번호 그 밖에 웹 페이지를 테스트할 때 필요한 파라미터들을 선언합니다.



이제 실제 실행될 테스트 케이스 클래스들을 선언할 차례인데요.

<test> 태그 안에 실행될 테스트 케이스 클래스들을 선언하시면 됩니다.


위에 보시면 두개의 <test> 태그가 있는데요.

첫번째 테스트에는 따로 파라미터가 선언돼 있지 않기 때문에 이 경우에는 Global Parameter를 사용합니다.


그리고 두번째는 따로 파라미터들을 선언했죠?

여기에 필요한 관리자용 어플리케이션 정보들을 선언해 주면 됩니다.


그리고 첫번째 테스트는 크롬 브라우저를 사용하고 두번째 브라우저는 IE 브라우저를 사용합니다.





이렇게 하나의 테스트 케이스에 여러 어플리케이션이나 여러 브라우저로 테스트 하도록 하는 방법은 <test> 태그를 여러개 사용해서 구현할 수 있습니다.



반응형


반응형

Internet Explorer Driver


인터넷 익스플로러드라이버는 webDriver의 wire 프로토콜을 implement한 standalone 서버 입니다. 이 드라이버는 XP, Vista, Windows 7에서 IE 6, 7, 8, 9 버전을 가지고 테스트를 했습니다.

이 드라이버는 브라우저의 32비트와 64 비트 버전을 지원합니다. 각 버전은 어떤 버전의 IEDriverServer.exe 에 따라 결정 됩니다. 32 비트 IEDriverServer.exe 가 실행이 되면 32비트 버전의 IE가 시작이 될 것이고 IEDriverServer.exe가 64비트라면 64비트 IE가 실행이 될 겁니다.

Installing


일단 standalon server 로 실행할 수 있는 IE버전다운로드 받아야 합니다. 그리고 여러분이 사용하는 PATH 에 복사해 넣습니다.


Pros (장점)

    Runs in a real browser and supports Javascript
    실제 브라우저가 실행되고 자바스크립트를 지원합니다.

Cons (단점)

    IEDriver는 Windows에서만 작동됩니다.
    Comparatively slow (though still pretty snappy :)
    비교적 느립니다.


Command-Line Switches


standalone으로 실행되니까, IE driver의 behavoir를 command-line argument들로 컨트롤 할 수 있습니다. 이 코맨드라인 argument의 값을 세팅하려면 여러분이 사용하는 language에 맞는 명령어를 사용해야 합니다. command line switch 는 아래 테이블에 있는 기능들을 지원합니다. -<switch>, --<switch> and /<switch> 가 사용 가능합니다.


Switch Meaning
--port=<portNumber> Specifies the port on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 5555.
--host=<hostAdapterIPAddress> Specifies the IP address of the host adapter on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 127.0.0.1.
--log-level=<logLevel> Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.
--log-file=<logFile> Specifies the full path and file name of the log file. Defaults to stdout.
--extract-path=<path> Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified.
--silent Suppresses diagnostic output when the server is started.




Important System Properties



아래의 시스템 프로퍼티들은 InternetExplorerDriver에 의해 사용됩니다. (자바의 경우 System.getProperty() and set using System.setProperty() 를 보세요. or the "-DpropertyName=value" command line flag)

Property What it means
webdriver.ie.driver The location of the IE driver binary.
webdriver.ie.driver.host Specifies the IP address of the host adapter on which the IE driver will listen.
webdriver.ie.driver.loglevel Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.
webdriver.ie.driver.logfile Specifies the full path and file name of the log file.
webdriver.ie.driver.silent Suppresses diagnostic output when the IE driver is started.



Required Configuration


    - IEDriverServer 를 다운 받아서 해당 PATH에 복사해 넣어야 합니다.
    - Windows Vista나 Windows 7에서 IE 7 이상의 브라우저를 사용할 때 각 zone의 모드를 Protected Mode로 세팅 해야 합니다. 이 값들을 Tools 메뉴에서 on 이나 off로 세팅될 수 있습니다. 그리고 Security tab을 클릭하시면 됩니다. 각 zone에 보면 그 탭의 아래 부분에 체크박스가 있을 겁니다. 이 체크박스 (Enable Protected Mode)를 체크하시고 적용하시면 됩니다.
    - browser zoom level은 반드시 100%로 세팅되어야 합니다. 그래야 마우스 이벤트가 정확한 지점에서 일어날 수 있습니다. 






Native Events and Internet Explorer

IE드라이버는 윈도우즈에서만 돌아가기 때문에 브라우저에서 마우스나 키보드를 작동시킬 때는 OS level(이것을 native 라고 부르기도 합니다.)의 이벤트를 사용해야 됩니다.  같은 기능에 대해 시뮬레이트되는 자바스크립트 이벤트를 사용하는 것과 좀 차이가 있습니다.이 native 이벤트를 사용할 때의 장점은 JavaScript sandbox에 의존하지 않는 다는 겁니다. 그래서 브라우저 내에서 정확한 자바스크립트 이벤트를 사용할 수 있습니다. 하지만 현재 마우스 이벤트에 대한 몇가지 이슈들이 있는데요. IE 브라우저 윈도우가 focus를 잃어 버릴 때나 element들 위에 hover를 실행할 때에 이슈들이 좀 있습니다.



Browser Focus

The challenge is that IE itself appears to not fully respect the Windows messages we send the IE browser window (WM_MOUSEDOWN and WM_MOUSEUP) if the window doesn't have the focus. Specifically, the element being clicked on will receive a focus window around it, but the click will not be processed by the element. Arguably, we shouldn't be sending messages at all; rather, we should be using the SendInput() API, but that API explicitly requires the window to have the focus. We have two conflicting goals with the WebDriver project.

First, we strive to emulate the user as closely as possible. This means using native events rather than simulating the events using JavaScript.

Second, we want to not require focus of the browser window being automated. This means that just forcing the browser window to the foreground is suboptimal.

An additional consideration is the possibility of multiple IE instances running under multiple WebDriver instances, which means any such "bring the window to the foreground" solution will have to be wrapped in some sort of synchronizing construct (mutex?) within the IE driver's C++ code. Even so, this code will still be subject to race conditions, if, for example, the user brings another window to the foreground between the driver bringing IE to the foreground and executing the native event.

The discussion around the requirements of the driver and how to prioritize these two conflicting goals is ongoing. The current prevailing wisdom is to prioritize the former over the latter, and document that your machine will be unavailable for other tasks when using the IE driver. However, that decision is far from finalized, and the code to implement it is likely to be rather complicated.



Hovering Over Elements


When you attempt to hover over elements, and your physical mouse cursor is within the boundaries of the IE browser window, the hover will not work. More specifically, the hover will appear to work for a fraction of a second, and then the element will revert back to its previous state. The prevailing theory why this occurs is that IE is doing hit-testing of some sort during its event loop, which causes it to respond to the physical mouse position when the physical cursor is within the window bounds. The WebDriver development team has been unable to discover a workaround for this behavior of IE.



Clicking <option> Elements or Submitting Forms and alert()


There are two places where the IE driver does not interact with elements using native events. This is in clicking <option> elements within a <select> element. Under normal circumstances, the IE driver calculates where to click based on the position and size of the element, typically as returned by the JavaScript getBoundingClientRect() method. However, for <option> elements, getBoundingClientRect() returns a rectangle with zero position and zero size. The IE driver handles this one scenario by using the click() Automation Atom, which essentially sets the .selected property of the element and simulates the onChange event in JavaScript. However, this means that if the onChange event of the <select> element contains JavaScript code that calls alert(), confirm() or prompt(), calling WebElement's click() method will hang until the modal dialog is manually dismissed. There is no known workaround for this behavior using only WebDriver code.

Similarly, there are some scenarios when submitting an HTML form via WebElement's submit() method may have the same effect. This can happen if the driver calls the JavaScript submit() function on the form, and there is an onSubmit event handler that calls the JavaScript alert(), confirm(), or prompt() functions.

This restriction is filed as  issue 3508 .



Multiple instances of InternetExplorerDriver


With the creation of the IEDriverServer.exe, it should be possible to create and use multiple simultaneous instances of the InternetExplorerDriver. However, this functionality is largely untested, and there may be issues with cookies, window focus, and the like. If you attempt to use multiple instances of the IE driver, and run into such issues, consider using the RemoteWebDriver and virtual machines.

There are 2 solutions for problem with cookies (and another session items) shared between multiple instances of InternetExplorer.

The first is to start your InternetExplorer in private mode. After that InternetExplorer will be started with clean session data and will not save changed session data at quiting. To do so you need to pass 2 specific capabilities to driver: ie.forceCreateProcessApi with true value and ie.browserCommandLineSwitches with -private value. Be note that it will work only for InternetExplorer 8 and newer, and Windows Registry HKLM_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main path should contain key TabProcGrowth with 0 value.

The second is to clean session during InternetExplorer starting. For this you need to pass specific ie.ensureCleanSession capability with true value to driver. This clears the cache for all running instances of InternetExplorer, including those started manually.



Running IEDriverServer.exe Remotely


The HTTP server started by the IEDriverServer.exe sets an access control list to only accept connections from the local machine, and disallows incoming connections from remote machines. At present, this cannot be changed without modifying the source code to the IEDriverServer.exe. To run the Internet Explorer driver on a remote machine, use the Java standalone remote server in connection with your language binding's equivalent of RemoteWebDriver.

반응형


반응형

HTML 에 보면 Select 태그가 있습니다.

그 안에 여러 Option 들이 있고 유저들은 DropDown 메뉴에서 그 Option 중 하나를 선택하게 되죠.





여기서 이 Option을 선택하도록 하는 것을 Selenium WebDriver로 구현할 때 아래 두가지 방법을 사용할 수 있습니다.


new Select(WebDriverAction.getElement(By.cssSelector("select[name='state']"))).selectByVisibleText("North Carolina");


이렇게 하면 select 메뉴 중 name인 태그안에 있는 옵션 중에서 blue인 텍스트를 찾아서 선택을 해 줍니다.



이 방법을 아래와 같이 조금 복잡하게 처리할 수도 있습니다.


    WebElement select = driver.findElement(By.cssSelector("select[name='state']"));
    List<WebElement> options = select.findElements(By.tagName("option"));
    for(WebElement option : options){
        if(option.getText().equals("North Carolina")) {
            option.click();
            break;
        }
    }

이 로직은 name이 color 인 select 라는 tag를 찾아서 이것을 select라는 WebElement 변수에 담아 놓습니다.
그리고 이 select 안에서 tagName 이 option인 것들을 List<WebElement> type으로 options라는 변수에 담아 놓습니다.

이 리스트를 for문으로 돌려서 option의 text가 blue 인 것을 찾아서 그 WebElement를 click 합니다.

그러면 원하는 blue가 선택이 됩니다.



반응형

JAVA DATE 함수 사용. 날짜 계산하기

2014. 1. 27. 07:25 | Posted by 솔웅


반응형

예전에 JAVA DATE 함수 사용법과 일/월/년 계산하는 로직을 블로그에 정리했던것 같은데...


얼마전에 월 계산하는 로직을 구현해야 되서 찾아보니까 없더군요.


이번 기회에 정리해 두어야 겠습니다.



이번에 제가 구현해야할 로직은 웹 페이지에서 유저가 두 날짜 범위를 입력하는 것을 Selenium WebDriver로 대신 처리하는 겁니다.


3개월 전 날짜와 오늘 날짜를 넣으면 됩니다.


    public static void enterDates() throws Exception {

        Date date = new Date();
        SimpleDateFormat sdformat = new SimpleDateFormat("MM/dd/yyyy");

        Date before3Mon = addMonth(date,-3);

        String today = sdformat.format(date);
        String before3Months = sdformat.format(before3Mon);
    }


today를 구하는 것은 쉽습니다.

첫번째는 오늘 날짜를 구하는 거고 두번째 줄은 날짜 포맷을 정해주는 겁니다.

월일년으로 포맷을 정했습니다.


그러면 date에는 오늘 날짜가 들어가 있습니다. Date type으로요.

밑에서 두번째 줄을 보면 만들어 두었던 Date Format을 사용해서 오늘 날짜를 월/일/년 포맷으로 만들어서 String으로 저장해 두는 부분이 나옵니다.



그 전줄에는 addMonth() 를 호출해서 3개우러 전 날짜를 date  포맷으로 받아오는 부분이 있습니다.

이 addMonth() 메소드를 보겠습니다.


    public static Date addMonth(Date date, int months) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, months);
        return cal.getTime();
    }


이 메소드는 Date 와 int 값을 파라미터로 받습니다.

그 내용을 보면..

처음에 Calendar 인스턴스를 변수에 담습니다.


이 Calendar 메소드가 날짜 계산하기 위해 자바에서 사용하는 API 입니다.

이 Calendar API의 setTime 메소드를 사용해서 전달받은 date를 세팅합니다.

그리고 add() 메소드를 사용해서 월을 계산합니다.



위에서 이 함수를 호출할 때 오늘 날짜와 -3을 인수로 전달했습니다.

이렇게 되면 오늘로부터 3개월 전의 날짜를 구할 수 있습니다.

이 값을 getTime() 메소드를 사용해서 Date 형식으로 만든 다음에 return 을 합니다.


이렇게 하면 오늘로부터 3개월 전 날짜를 구할 수 있습니다.

인수를 달리하면 1달 후 던지 10개월 전이던지 원하는 날짜를 얻을 수 있겠죠.




반응형


반응형


오늘은 Selenium WebDriver로 테스트 케이스를 만들다가 가끔 아주 유용하게 쓰이는 로직을 따로 정리합니다.


public static void sample01(String selectItem) throws Exception {

List<WebElement> sampleValue = driver.findElement(By.cssSelector("div[id='aaa'][class='bbb'] *"));


for(WebElement sample : sampleValue)

{

if(sample.getText().equalsIgnoreCase(selectItem))

sample.click();

}

}



위 코드는 클릭해야 되는 아이템이 딱히 unique 한 id나 class 뭐 이런걸 갖고 있지 않아서 Selenium으로 그 WebElement를 가져오기 힘들 때 아주 유용하게 사용하고 있습니다.


해당 WebElement의 상위 WebElement들 중 확실하게 unique 하게 추려낼 수 있는 WebElement를 sampleValue에다 담습니다. 위에서는 샘플로 id 가 aaa 이고 클래스가 bbb 인 div WebElement가 그에 해당됩니다.


이 div WebElement 내에는 또 다른 div나 tag들이 있을 겁니다.

for 문으로 이 sampeValue를 돌리면서 그 하위 WebElement들의 text들을 불러 옵니다.

이 텍스트가 원하는 텍스트와 같을 때 이 텍스트를 click 할 수 있습니다.


위 경우는 예를 들어 Edit이라는 링크가 있는데 해당 화면에는 이 Edit 이라는 링크가 많고 내가 딱히 클릭하고 싶은 Edit 링크는 어떤 unique 한 Attribute도 가지고 있지 않을 때 사용할 수 있습니다.

클릭하고자 하는 Edit을 감싸고 있는 부모 WebElement들 중에서 unique 한 속성을 가지고 있는 놈을 찾아서 List에 담고 이 리크트를 돌리면서 그 안에 있는 텍스트가 Edit이면 그것을 클릭하는 겁니다.

여기서 충족되어야 할 조건은 리스트에 담긴 부모 엘리먼트 안에는 Edit이라는 글자를 가지고 있는 WebElement가 내가 클릭하고자 하는 그 Edit WebElement 딱 하나라야 겠죠.





public static void pageNavigationSampe(String selectItem) throws Exception{

int exist = 0;

int firstPage = 0;

int pageNum = 1;


do{

if(firstPage==0) {

exist = checkAAAexist(selectItem);

firstPage=1;

} else {

pageNum = pageNum+1;

String PageCss = "a[id='goToPageId][pagenumber='" + pageNum + "']";

driver.findElement(By.cssSelector(PageCss)).click();

Thread.sleep(5000);

exist=checkAAAexist(selectItem);

}

} while(exist==0);

}


public static int checkAAAexist(String selectItem) throws Exception {

List<WebElement> theItem = driver.findElements(By.cssSelector("input[type='button'][value='theItem']"));

int exist = 0;


for(WebElement clickItem : theItem)

{

if(clickItem.getAttribute("onClick").contains(vehicle)) {

clickItem.click();

exist=1;

Thread.sleep(3000);

break;

}

}


return exist;

}


위 예제는 게시판 형태로 돼 있는 페이지 중에서 내가 선택하고자 하는 WebElement가 어떤 때는 첫번째 페이지에 있다가 또 어떤때는 두번째 페이지에 있고...

뭐 이렇게 테스트시마다 다른 페이지에 있을 수 있는 아이템을 다뤄야 할 때 사용할 수 있습니다.

상황은 클릭해야할 버튼이 있는데 이 버튼은 테이블의 각 row마다 있고 그 중 하나만 클릭해야 됩니다.

이 버튼을 나타내는 속성은 공통된 부분이 있을 겁니다.

그걸 checkAAAexist() 메소드에서 처럼 theItem 에 리스트로 담구요.

이 리스크를 for 문으로 돌리면서 원하는 텍스트를 가지고 있는 놈이 나오면 그 놈을 클릭합니다.

이건 위의 예제와 별반 다르지 않은데요.

문제는 이 페이지에 없으면 다음 페이지로 넘어가야 한다는 거죠.

그래서 pageNavigationSampe() 메소드를 만든겁니다.


처음에 checkAAAexist()를 호출해서 원하는 놈이 없다는 결론을 받으면 다음 페이지를 클릭하는 거죠.

여기서 중요한것은 각 페이지마다 걸려 있을 링크 (1,2,3,4... 이런 숫자에 링크들이 있겠죠.)..

이 링크들의 속성들의 규칙을 알아야 합니다.

대개 위 예제처럼 다 똑같고 1페이지 2페이지 3페이지 등등에 해당되는 링크들은 해당 숫자들이 들어가는 부분이 있을 겁니다.

그것을 위에서와 같이 해당 숫자 부분을 매번 +1 씩 해줘서 넣으면 계속 다음 페이지를 클릭할 수 있습니다.

만약에 원하는 놈이 나오면 클릭하고 break; 를 만나서 해당 루프를 빠져 나오겠죠.

위 로직에서는 이 break; 가 없어도 while() 문에서 체크해서 빠져 나오게 만들었지만.. 확실하게 하기 위해서 break; 문도 넣었습니다.

중간에 Thread.sleep()을 넣은 이유는 웹 UI에서는 링크를 클릭한 후 다음 페이지로 넘어가는데 시간이 걸리니까 곧바로 다음 Action을 취하면 Fail이 되는 경우가 많습니다.

그래서 강제로 Thread.sleep()을 넣어 준 겁니다.

원래 이상적인 방법은 다음 페이지에 나오는 특정 WebElement를 wait하는 방법이 있긴 한데요.

이 예제에서는 그것까지 다루지는 않겠습니다.


위 예제 중 Selenium WebDriver의 API와 약간 다른부분이 있을 수 있습니다.

제가 참여하고 있는 프로젝트에서는 이 Selenium WebDriver를 편리하게 다루가 위한 프레임워크를 따로 제작해서 사용하고 있거든요.

그래서 그 프레임워크의 API가 있는 부분은 따로 Selenium WebDirver의 API로 풀어서 넣었는데요.

직접 돌려서 결과를 해보면서 코드를 바꾼에 아니라서 혹시 맞지 않는 부분이 있을 수 있습니다.

참고하세요.


반응형


반응형

오늘 배운 Tip 하나 정리 해 둡니다.


Alert 창 떴을 때 Control 하는 법


Alert alert = driver.switchTo().alert();

alert.accept();


public void checkAlert() {
    try {
        WebDriverWait wait = new WebDriverWait(driver, 2);
        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        alert.accept();
    } catch (Exception e) {
        //exception handling
    }
}


driver.switchTo().alert().accept();
or
driver.switchTo().alert().dismiss();

// Get a handle to the open alert, prompt or confirmation
Alert alert = browser.switchTo().alert();
// Get the text of the alert or prompt
alert.getText();
// And acknowledge the alert (equivalent to clicking "OK")
alert.accept();

WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8081/TestAutomation/Escape.jsp");
driver.manage().window().maximize();

WebElement txtBxHandle = driver.findElement(By.name("txtName"));        
txtBxHandle.sendKeys("Socrates");

Actions action = new Actions(driver);
action.sendKeys(Keys.ESCAPE).perform();

WebElement BnEnable = driver.findElement(By.name("btnSubmit"));
BnEnable.click();


반응형


반응형

Handling iFrames using WebDriver


inline frame은 현재의 HTML 문서 내에 다른 문서를 넣을 때 사용됩니다. 즉 iframe은 웹페이지 안에 있는 웹페이지를 말하는거죠. iframe은 별도로 DOM을 가지고 있습니다.

iframe을 사용하는 HTML 소스코드는 아래와 같이 사용하시면 됩니다





위의 코드를 보면 iframe안에 또 다른 iframe이 있는 걸 보실 수 있을 겁니다. 안쪽의 iframe으로 가려면 바깥쪽의 iframe 을 지나가야 되고 또 그 안쪽의 iframe 안에도 body가 있습니다.

그리고 나서 다시 안쪽의 iframe은 을 나와서 바깥쪽 iframe 까지 나오면 이제 OK 버튼을 보게 됩니다. 테스트를 작성하려면 이 과정을 거쳐야 합니다. iframe 안에 있는 element에 직접 접근하는 것은 가능하지 않습니다. iframe은 자신만의 DOM element를 가지고 있어서 그 안의 element들을 다루려면 switch to 를 해서 접근해야 합니다.


Selects the frame 1

driver.switchTo().frame("frame1");

Selects the frame2

driver.switchTo().frame("frame2");

Switching back to the parent window

driver.switchTo().defaultContent(); // 이제 iframe 바깥으로 완전히 빠져 나온 겁니다.

iframe의 value를 알지 못할 때도 있는데요. 그럴 때는 아래와 같이 tagName 메소드를 사요ㅇ해서 그 name을 얻을 수 있습니다.

driver.switchTo().frame(driver.findElements(By.tagName("iframe").get(0));



아래 메소드를 사용해서 iframe을 선택하실 수 있습니다.

    frame(index)
    frame(Name of Frame [or] Id of the frame
    frame(WebElement frameElement)
    defaultContent()


반응형


반응형

오늘은 회사에서 작업하다가 체험한 유용한 로직을 정리해 두어야 겠다.



<input onclick="display('0000','AAAA','y')" value="test" class="test" type="button">

<input onclick="display('0001','BBBB','y')" value="test" class="test" type="button">

<input onclick="display('0002,'CCCC','y')" value="test" class="test" type="button">

<input onclick="display('0003','DDDD','y')" value="test" class="test" type="button">

<input onclick="display('0004','EEEE','y')" value="test" class="test" type="button">

<input onClick="display('0005','FFFF','y')" value="test" class="test" type="button">



Selenium WebDriver로 Automation Testing 작업을 하고 있는데 위와 같은 링크가 나타났다.

예를 들어 이중에서 세번째 것을 클릭해야 하는데 ... 이걸 어떻게 클릭해야 할지....


여러번 헤매다가 찾아낸 방법이다.


List<WebElement> solution = WebDriverAction.getElemtnts(By.cssSelector("input[type='button'][value='test'"));

for(WebElement aaa : solution)

{

if(aaa.getAttribute("onClick").contains("CCCC")) {

aaa.click();

}

}




일단 cssSelector를 사용해서 type과 value 조합으로 WebElement들을 모드면 위의 input 들만 모일것 같다.

WebDriverAction.getElement를 사용해서 이 조합으로 된 WebElement들을 List로 담는다.


그리고 for 루프를 돌리면서 onClick이라는 attribute의 값들을 받아서 그 중에 CCCC를 포함하고 있는 놈이 걸리면 그 놈을 클릭한다.


해결하고 나니까 간단한데 이걸 처음 봤을 때는 사실 좀 헤맸다.



그리고 아래와 같은 코드도 있다.


driver.findElement(By.id("testId")).click();

List<WebElement> solution = WebDriverAction.getElemtnts(By.cssSelector("div[class="testclass"));

for(WebElement aaa : solution)

{

if(aaa.getText().equalsIgnoreCase("Year") {

aaa.click();

}

}



이것은 select option 코드에서 특정 option을 선택할 때 사용한 거다.

이걸 사용한 select option은 일반적이지는 않았다.



하여간 이렇게 WebElement들을 List에 담아서 for 문을 돌리면서 특정 조건에 맞으면 해당 아이템을 클릭하는 로직이 실무에서는 많이 사용되는 것 같다.




반응형


반응형

Why using JavascriptExecutor in WebDriver can be dangerous


나는 자주 JavascriptExecutor를 사용해서 자바스크립트를 running 하라는 권고를 듣는다. 예를 들어 개발자 컴퓨터에서는 pass를 하는데 functional test machine에서는 fail을 하는 테스트를 어느 프로젝트에서 본 적이 있다. 그 코드는 아래와 같았다.

driver.findElement(By.cssSelector(".save")).click();

그래서 개발자는 아래와 같이 이 코드를 고쳤다.

((JavascriptExecutor)driver).executeScript("$('.save').click();");


  이 코드는 제대로 작동 했다.




추측컨대 웹 드라이버는 style="display: none;" 과 함께 DOM안에 항상 존재하는 버튼을 찾게 된다. 하지만 버튼이 visible 될때까지 기다리지 않기 때문에 이 버튼 click은 fail이 되게 된다.


실제로 이 테스트는 아래와 같다.


- open the dialog (dialog 를 연다)
- wait for the button to become visible (버튼이 visible 할 때까지 기다린다)
- click the button (버튼을 클릭한다)

만약에 우리가 자바스크립트를 사용했다면 버튼이 visible 할 때까지 기다릴 필요가 없다. 그러니까 자바스크립트가 더 빠르고 제대로 동작하게 된다.

뭐 제대로 작동하니까 문제가 없을까? 그렇지 않다. 이 save 버튼이 scroll 하지 않는 javascript dialog 에 있게 된다. 만약 페이지가 scroll up이나 down을 하게 되도 이 dialog 는 그대로 남게 된다. 이 dialog는 항상 위에서부터 120px 거리에 있다. 이 테스트가 돌아갈 때 dialog 830px hige에 데이터를 생성하게 된다. 이것은 아래에서 950px에 놓이게 된다. 개발자의 machine은 1600X1200 해상도 이다. 이 해상도에서는 이 dialog가 완전히 다 보이게 된다. functional test machine은 해상도가 800X600 이다. 이렇게 되면 이 dialog의 밑부분이 보이지 않게 된다. 브라우저가 full screen이어도 이 save button을 볼 수 없게 되는 것이다.


그래서 개발자 machine에서 WebDriver는 보여서 이 save 버튼을 click 하게 된다. functional test machine 에서는 visible 하지 않고 이것을 scroll 할 수도 없기 때문에 save button이 보이지 않게 된다. 그래서 click이 안 되게 된다.

자바스크립트를 보이든 보이지 않든 상관없이 버튼이 click될 수 있도록 바꾸면 functional test machine에서는 pass가 되더라도 800X600 을 사용하는 사람들은 이 버튼을 클릭할 수 없게 된다.

이런 경우 자바스크립트를 사용하면 실제 requirement의 상황에 정확하게 일치하는 테스트가 되지 않을 수도 있고 이런 경우는 여러분의 tests report를 false가 되도록 해야 한다.


반응형
이전 1 2 3 4 5 6 7 ··· 9 다음