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

최근에 받은 트랙백

글 보관함


지난 글에서 다룬 GoogleSearch 클래스를 Page Object 를 사용해서 만드는 방법을 알아보겠습니다.


이렇게 Page Object를 사용하는 방법으로 사용하려면 그 기능별로 여러 클래스를 만들어야 합니다.


지난 GoogleSearch 클래스는 한개의 클래스에서 모든 작업이 이루어 졌기 때문에 한개의 JAVA 파일만 보면 됐습니다.

그런데 Page Object를 사용하는 버전에서는 여러개의 클래스 즉 여러개의 JAVA 파일을 봐야합니다.


우선 Page Object 를 사용하는 GoogleSearch 에는 어떤 클래스들이 있는지 알아보겠습니다.



우선 처음에 볼 부분은 GoogleSearch_withPageObject.java 입니다.


/**
* Google search demo class. This class shows how to use page objects.
* Compare with "GoogleSearch.java" class, and see how to use page objects.
*
* @author Chon Chung
*
*/
public class GoogleSearch_withPageObject {

    public static void main(String[] args) {
            GoogleSearch.testGoogleSearch();
            try{
                    GoogleSearch.testGoogleSuggest();
            }catch(Exception e){
                    System.out.println("Unable to perform testGoogleSuggest() - " +
                                                            e.getMessage());
            }
    }
   
    public static void testGoogleSearch(){
            //Create a new instance of GoogleSearch page
            GoogleSearchPage googleSearchPage = new GoogleSearchPage(new HtmlUnitDriver());

        // go to Google ("http://www.google.com")
            googleSearchPage.open();

        // Enter something to search for
            googleSearchPage.enterSearchForm("Cheese!");

        // Now submit the form, and get the next page object
            GoogleSearchResultPage googleSearchResultPage = googleSearchPage.submitForm();
              

        // Verify: Check the title of the page        
        String pageTitle = googleSearchResultPage.getTitle();
        System.out.println("Page title is: " + pageTitle);
        assertTrue("Got title: " + pageTitle, pageTitle.contains("Cheese!"));
    }
   
    public static void testGoogleSuggest() throws Exception {
               
        GoogleSearchSuggestPage googleSuggestPage = new GoogleSearchSuggestPage(new FirefoxDriver());
       
        // Go to the Google Suggest home page: "http://www.google.com/webhp?complete=1&hl=en"
        googleSuggestPage.open();
       
        // Enter the query string "Cheese", and get the list the suggestions
        List<WebElement> allSuggestions = googleSuggestPage.getSearchSuggestions("Cheese");
       
        for (WebElement suggestion : allSuggestions) {
            System.out.println(suggestion.getText());
        }
     }
}
/**
* Further reading:
* 1. Selenium webdriver page object:
*                 http://stackoverflow.com/questions/10315894/selenium-webdriver-page-object
* 2. Using Page Objects with Selenium and Web Driver 2.0
*                 http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/
* 3. PageFactory
*                 http://code.google.com/p/selenium/wiki/PageFactory
* 4. Ben Burton's WebDriver Best Practices
*                 Video -- http://vimeo.com/44133409
* http://benburton.github.com/presentations/webdriver-best-practices/
*                
*/


main() 메소드는 이전의 GoogleSearch 클래스와 똑 같습니다.


testGoogleSearch() 메소드를 보면 GoogleSearch 에서는 먼저 WebDriver 객체를 만들고 그 객체를 사용해서 구글 페이지를 열었는데요.


이번에는 GoogleSearchPage 의 객체를 생성해서 사용합니다.


이 얘기는 GoogleSearchPage라는 클래스가 따로 있고 이 곳에서 WebDriver를 초기화 하는 작업을 한다는 얘기 입니다.



그러면 GoogleSearchPage.java를 볼까요?


/**
* Google Search Page Object.
* @author Chon Chung
*/
public class GoogleSearchPage extends PageBase{
       
        private final static String pageTitle = "Google";
       
        private final static String SEARCH_FIELD_NAME = "q";

        /** Constructor */
        public GoogleSearchPage(WebDriver driver){
                super(driver, pageTitle);

                // set the default URL
                URL = "http://www.google.com";
        }
       
        /** Returns the default URL */
        public String getURL(){
                return URL;
        }
       
        /** Enter the Search Text in the Search form field */
        public void enterSearchForm(String searchText){
                driver.findElement(By.name(SEARCH_FIELD_NAME)).sendKeys(searchText);                
        }
       
        /** Submit the form and return the next page object.
         * Seperate function should be in a seperate method. */
        public GoogleSearchResultPage submitForm(){
                driver.findElement(By.name(SEARCH_FIELD_NAME)).submit();
                return new GoogleSearchResultPage(driver);
        }
}


GoogleSearchPage()라는 생성자가 있죠? 여기에서 super 메소드를 사용합니다.

이 얘기는 이 클래스는 어떤 다른 클래스를 상속 받았다는 얘기입니다.

좀 위에 보니까 PageBase 클래스를 상속 받았네요.


소스 분석은 나중에 하고 오늘은 어떤 클래스들이 Page Object를 위해 사용됐는지 보기로 했으니까 다른 메소드들을 분석하는 것은 다음 글에서 하겠습니다.


그럼 PageBase 클래스를 보죠.


/**
* Page Object base class. It provides the base structure
* and properties for a page object to extend.
*
* @author Chon Chung
*/
public class PageBase {
         /** Default URL */
         protected String URL;       
       
         /** This page's WebDriver */
         protected WebDriver driver;
       
         /** Expected Page Title. This will be used in isPageLoad()
         * to check if page is loaded. */
         protected String pageTitle;
       
       
         /** Constructor */
         public PageBase(WebDriver driver, String pageTitle) {
                 this.driver = driver;
                 this.pageTitle = pageTitle;
         }
       
         /**
         * Check if page is loaded by comparing
         * the expected page-title with an actual page-title.
         **/
         public boolean isPageLoad(){
                 return (driver.getTitle().contains(pageTitle));
         }
       
       
         /** Open the default page */
         public void open(){
                 driver.get(URL);
         }
       
       
         /** Returns the page title */
         public String getTitle() {
                 return pageTitle;
         }
       
         /** Returns the default URL */
         public String getURL() {
                return URL;
         }
       
         /**
         * Send text keys to the element that finds by cssSelector.
         * It shortens "driver.findElement(By.cssSelector()).sendKeys()".
         * @param cssSelector
         * @param text
         */
         protected void sendText(String cssSelector, String text) {
                        driver.findElement(By.cssSelector(cssSelector)).sendKeys(text);
         }
       
         /** Is the text present in page. */
         public boolean isTextPresent(String text){
                 return driver.getPageSource().contains(text);
         }
       
         /** Is the Element in page. */
         public boolean isElementPresent(By by) {
                        try {
                                driver.findElement(by);//if it does not find the element throw NoSuchElementException, thus returns false.
                                return true;
                        } catch (NoSuchElementException e) {
                                return false;
                        }
         }

         /**
         * Is the Element present in the DOM.
         *
         * @param _cssSelector                 element locater
         * @return                                        WebElement
         */
         public boolean isElementPresent(String _cssSelector){
                        try {
                                driver.findElement(By.cssSelector(_cssSelector));
                                return true;
                        } catch (NoSuchElementException e) {
                                return false;
                        }
         }
       

         /**
                * Checks if the elment is in the DOM and displayed.
                *
                * @param by - selector to find the element
                * @return true or false
                */
         public boolean isElementPresentAndDisplay(By by) {
                        try {                       
                                return driver.findElement(by).isDisplayed();
                        } catch (NoSuchElementException e) {
                                return false;
                        }
         }
       
         /**
         * Returns the first WebElement using the given method.        
         * It shortens "driver.findElement(By)".
         * @param by                 element locater.
         * @return                 the first WebElement
         */
         public WebElement getWebElement(By by){
                         return driver.findElement(by);                        
         }
}
/**
* Further reading:
* 1. Selenium webdriver page object:
*                 http://stackoverflow.com/questions/10315894/selenium-webdriver-page-object
* 2. Using Page Objects with Selenium and Web Driver 2.0
*                 http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/
* 3. PageFactory
*                 http://code.google.com/p/selenium/wiki/PageFactory
*/


PageBase() 생성자를 보시면 WebDriver와 pageTitle을 세팅합니다.

이렇게 3개의 클래스만 사용되나요?

아까 봤던 GoogleSearch_withPageObject 클래스의 testGoogleSearch() 메소드를 다시 보겠습니다.


좀 아래로 내려가니까 GoogleSearchResultPage 객체를 만드는 부분이 있습니다.

이 클래스도 따로 있는 것 같습니다.


/**
* Google Search Result Page Object.
* @author Chon Chung
*
*/
public class GoogleSearchResultPage extends PageBase{
       
        private static final String resultStats_id = "resultStats";
        private final static String pageTitle = "Google Search";
       
       
        public GoogleSearchResultPage(WebDriver driver){
                super(driver, pageTitle);        
        }
        
        /** Returns the search ResultStat. */
        public String getSearchResultStat(){
                return driver.findElement(By.id(resultStats_id)).getText();
        }  
}


여기서도 PageBase 클래스를 상속하네요.

이 PageBase 클래스는 저 위에 있으니까 다시 볼 필요는 없습니다.


그러면 testGoogleSearch() 메소드는 다 봤고 이어서 testGoogleSuggest() 메소드를 보겠습니다.

여기에서는 GoogleSearchSuggestPage 클래스에 대한 객체를 생성하네요.

이 GoogleSearchSuggestPage.java 파일도 사용됐습니다.


public class GoogleSearchSuggestPage extends PageBase{
        private final static String pageTitle = "Google";

        private final static String SEARCH_FIELD_NAME = "q";
       
        /** Constructor */
        public GoogleSearchSuggestPage(WebDriver driver){
                super(driver, pageTitle);

                // set the default URL
                URL = "http://www.google.com/webhp?complete=1&hl=en";
        }

        /** Enter the Search Text in the Search form field */
        public void enterSearchForm(String searchText){
                driver.findElement(By.name(SEARCH_FIELD_NAME)).sendKeys(searchText);                
        }
       
        /** Submit the form and return the next page object.
         * Seperate function should be in a seperate method. */
        public GoogleSearchResultPage submitForm(){
                driver.findElement(By.name(SEARCH_FIELD_NAME)).submit();
                return new GoogleSearchResultPage(driver);
        }

        /**
         * Enter the query string, and get the list of the suggestions
         * It use WaitTool to wait for the div (class=gsq_a).
         *
         * @param searchText the query string to search for
         * @return the list of the google search suggestions
         */
        public List<WebElement> getSearchSuggestions(String searchText){
        // Enter the query string "Cheese"
                driver.findElement(By.name(SEARCH_FIELD_NAME)).sendKeys(searchText);

        // Wait and get the list of suggestions
        List<WebElement> allSuggestions = WaitTool.waitForListElementsPresent(driver, By.className("gsq_a"), 5);
                return allSuggestions;
        }
}



여기서도 PageBase 클래스가 상속됐습니다. 다시 볼 필요는 없겠죠.

그 다음에 이 파일 안에서 다른 custom 클래스에 대한 객체를 만드는 부분은 없습니다.


다시 GoogleSearch_withPageObject 클래스로 돌아가죠.

testGoogleSuggest() 메소드를 보니까 다른 custom 클래스에 대한 객체를 생성하는 부분은 없습니다.


그러면 지금까지 살펴본 클래스들이 GoogleSearch.java 를 Page Object를 사용하는 버전으로 바꿨을 때 만든 클래스들 입니다.


PageBase.java

GoogleSearchPage.java

GoogleSearchResultPage.java

GoogleSearchSuggestPage.java

GoogleSearch_withPageObject.java


총 이렇게 5개의 파일이 사용됐습니다.


지난번 GoogleSearch.java에서는 단 한개의 파일만 사용했는데 똑 같은 일을 하는 Page Object를 만들기 위해 이렇게 파일을 5개로 쪼개서 기능을 부여 했네요.


다음 글에서는 각 클래스별로 어떤 일을 하고 전체적으로 어떻게 연관을 맺고 실행이 되는지를 알아보겠습니다.



반응형

Comment