From 9c723c4c285b88c2fd5d9b20cac3f485de3cafb1 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 10:49:31 -0500 Subject: [PATCH 01/17] QAR-49187: Corrected README. --- demo/README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/demo/README.md b/demo/README.md index d012dc0..f8e26e5 100755 --- a/demo/README.md +++ b/demo/README.md @@ -5,21 +5,18 @@ This directory contains a demo of the Robot Page Objects package. It demonstrate suprememly readable Robot test leveraging Selenium2Library to create page object libraries, which are usable in Robot and outside of Robot. -How to run the demos +How to run the demo -------------------- -1. Create a virtual environment -2. pip install . -3. activate the virtual environment -4. $ pybot -vbrowser:firefox -vbaseurl:http://www.google.com test_google.robot +1. pip install robotframeworkpageobjects +2. $ pybot -vbrowser:firefox -vbaseurl:http://www.ncbi.nlm.nih.gov test_pubmed.robot To run the Python unittest example: -$ export PO_BASURL=http://www.google.com -$ python test_google.py +$ export PO_BASURL=http://www.ncbi.nlm.nih.gov +$ export PO_BROWSER=firefox +$ python test_pubmed.py To run the unittest example in Firefox, set the browser environment variable: $ export PO_BASURL=http://www.google.com $ export PO_BROWSERL=firefox -$ python test_google.py - -This demo no longer works in Phantomjs. We plan on fixing that in the future. +$ python test_pubmed.py From 2cb5dc1b1cf55aae0fefa63d1311cd6f6e6a2fac Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:11:49 -0500 Subject: [PATCH 02/17] Renamed modules --- demo/google.py | 63 --------------------------------------------- demo/test_google.py | 20 -------------- demo/test_pubmed.py | 20 ++++++++++++++ 3 files changed, 20 insertions(+), 83 deletions(-) delete mode 100755 demo/google.py delete mode 100755 demo/test_google.py create mode 100755 demo/test_pubmed.py diff --git a/demo/google.py b/demo/google.py deleted file mode 100755 index c8e0a89..0000000 --- a/demo/google.py +++ /dev/null @@ -1,63 +0,0 @@ -from robotpageobjects import Page, robot_alias -from robot.utils import asserts - - -class GoogleHomePage(Page): - """ Models the Google home page """ - - name = "Google" - uri = "/" - - selectors = { - "search input": "xpath=//input[@name='q']", - "search button": "xpath=//button[@name='btnG']|//input[@name='btnG']", - } - - - @robot_alias("type_in__name__search_box") - def type_in_search_box(self, txt): - self.input_text("search input", txt) - return self - - @robot_alias("click__name__search_button") - def click_search_button(self): - self.click_button("search button") - return GoogleSearchResultPage() - - @robot_alias("search__name__for") - def search_for(self, term): - self.type_in_search_box(term) - return self.click_search_button() - - -class GoogleSearchResultPage(Page): - """Models a Google search result page. For example: - http://www.google.com/#q=cat """ - - uri_template = "/#q={term}" - - selectors = { - "nth result link": "xpath=(//li[@class='g'])[{n}]//div//h3//a | (//li[@class='g'])[{n}]/h3/a", - } - - @robot_alias("click_result_on__name__") - def click_result(self, i): - locator = self.resolve_selector("nth result link", n=int(i)) - self.click_link(locator) - return DestinationPage() - -class DestinationPage(Page): - - uri_template = "/{path}" - - selectors = { - "title element": "xpath=//head//title", - } - - @robot_alias("__name__title_should_contain") - def title_should_contain(self, str, ignore_case=True): - ref_str = str.lower() if ignore_case else str - ref_str = ref_str.encode("utf-8") - title = self.get_title().encode("utf-8").lower() - asserts.assert_true(ref_str in title, "%s does not contain %s" %(title, ref_str)) - return self diff --git a/demo/test_google.py b/demo/test_google.py deleted file mode 100755 index 1e39327..0000000 --- a/demo/test_google.py +++ /dev/null @@ -1,20 +0,0 @@ -from google import GoogleHomePage -import unittest - - -class GoogleTestCase(unittest.TestCase): - - def setUp(self): - self.google_homepage = GoogleHomePage() - self.google_homepage.open() - - def test_first_result_page_title_should_contain_search_term(self): - search_result_page = self.google_homepage.search_for("cat") - self.destination_page = search_result_page.click_result(1) - self.destination_page.title_should_contain("cat") - - def tearDown(self): - self.destination_page.close() - -if __name__ == "__main__": - unittest.main() diff --git a/demo/test_pubmed.py b/demo/test_pubmed.py new file mode 100755 index 0000000..8a52f2e --- /dev/null +++ b/demo/test_pubmed.py @@ -0,0 +1,20 @@ +from pubmed import PubmedHomePage +import unittest + + +class PubmedTestCase(unittest.TestCase): + + def setUp(self): + self.pubmed_homepage = PubmedHomePage() + self.pubmed_homepage.open() + + def test_first_result_page_title_should_contain_search_term(self): + pubmed_docusm_page = self.pubmed_homepage.search_for("cat") + self.article_page = pubmed_docsum_page.click_result(1) + self.article_page.title_should_contain("cat") + + def tearDown(self): + self.article_page.close() + +if __name__ == "__main__": + unittest.main() From 0f5ad640183c3b14b986a3db417d695230821004 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:12:11 -0500 Subject: [PATCH 03/17] Added pubmed.py --- demo/pubmed.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 demo/pubmed.py diff --git a/demo/pubmed.py b/demo/pubmed.py new file mode 100755 index 0000000..439a7b1 --- /dev/null +++ b/demo/pubmed.py @@ -0,0 +1,64 @@ +from robotpageobjects import Page, robot_alias +from robot.utils import asserts + + +class PubmedHomePage(Page): + """ Models the Pubmed home page at: + HOST://ncbi.nlm.nih.gov/pubmed""" + + name = "Pubmed" + uri = "/" + + selectors = { + "search input": "id=term", + "search button": "id=search", + } + + + @robot_alias("type_in__name__search_box") + def type_in_search_box(self, txt): + self.input_text("search input", txt) + return self + + @robot_alias("click__name__search_button") + def click_search_button(self): + self.click_button("search button") + return PubmedDocsumPage() + + @robot_alias("search__name__for") + def search_for(self, term): + self.type_in_search_box(term) + return self.click_search_button() + + +class PubmedDocsumPage(Page): + """Models a Pubmed search result page. For example: + http://www.ncbi.nlm.nih.gov/pubmed?term=cat """ + + uri_template = "/?term={term}" + + selectors = { + "nth result link": "xpath=(//div[@class='rslt'])[{n}]/p/a", + } + + @robot_alias("click_result_on__name__") + def click_result(self, i): + locator = self.resolve_selector("nth result link", n=int(i)) + self.click_link(locator) + return PubmedArticlePage() + +class PubmedArticlePage(Page): + + uri_template = "pubmed/{article_id}" + + selectors = { + "title element": "xpath=//head//title", + } + + @robot_alias("__name__title_should_contain") + def title_should_contain(self, str, ignore_case=True): + ref_str = str.lower() if ignore_case else str + ref_str = ref_str.encode("utf-8") + title = self.get_title().encode("utf-8").lower() + asserts.assert_true(ref_str in title, "%s does not contain %s" %(title, ref_str)) + return self From 73cc48b8e41e9027feabf01c34b675c494fdcd1a Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:51:50 -0500 Subject: [PATCH 04/17] QAR-49187: Got python test working --- demo/pubmed.py | 18 +++++++----------- demo/test_pubmed.py | 4 ++-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/demo/pubmed.py b/demo/pubmed.py index 439a7b1..04baa82 100755 --- a/demo/pubmed.py +++ b/demo/pubmed.py @@ -7,7 +7,7 @@ class PubmedHomePage(Page): HOST://ncbi.nlm.nih.gov/pubmed""" name = "Pubmed" - uri = "/" + uri = "/pubmed" selectors = { "search input": "id=term", @@ -35,7 +35,7 @@ class PubmedDocsumPage(Page): """Models a Pubmed search result page. For example: http://www.ncbi.nlm.nih.gov/pubmed?term=cat """ - uri_template = "/?term={term}" + uri_template = "/pubmed/?term={term}" selectors = { "nth result link": "xpath=(//div[@class='rslt'])[{n}]/p/a", @@ -49,16 +49,12 @@ def click_result(self, i): class PubmedArticlePage(Page): - uri_template = "pubmed/{article_id}" + uri_template = "/pubmed/{article_id}" - selectors = { - "title element": "xpath=//head//title", - } - - @robot_alias("__name__title_should_contain") - def title_should_contain(self, str, ignore_case=True): + @robot_alias("__name__body_should_contain") + def body_should_contain(self, str, ignore_case=True): ref_str = str.lower() if ignore_case else str ref_str = ref_str.encode("utf-8") - title = self.get_title().encode("utf-8").lower() - asserts.assert_true(ref_str in title, "%s does not contain %s" %(title, ref_str)) + body_txt = self.get_text("css=body").encode("utf-8").lower() + asserts.assert_true(ref_str in body_txt, "body text does not contain %s" %ref_str) return self diff --git a/demo/test_pubmed.py b/demo/test_pubmed.py index 8a52f2e..9f9ee51 100755 --- a/demo/test_pubmed.py +++ b/demo/test_pubmed.py @@ -9,9 +9,9 @@ def setUp(self): self.pubmed_homepage.open() def test_first_result_page_title_should_contain_search_term(self): - pubmed_docusm_page = self.pubmed_homepage.search_for("cat") + pubmed_docsum_page = self.pubmed_homepage.search_for("cat") self.article_page = pubmed_docsum_page.click_result(1) - self.article_page.title_should_contain("cat") + self.article_page.body_should_contain("cat") def tearDown(self): self.article_page.close() From 0c3e2663eae9985de7beffd1cb637a10ba90027b Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:55:53 -0500 Subject: [PATCH 05/17] QAR-49187: demos working --- demo/test_pubmed.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 demo/test_pubmed.txt diff --git a/demo/test_pubmed.txt b/demo/test_pubmed.txt new file mode 100755 index 0000000..08cfdaf --- /dev/null +++ b/demo/test_pubmed.txt @@ -0,0 +1,14 @@ +*** Settings *** +Documentation My first IFT tests +... +Library pubmed.PubmedHomePage +Library pubmed.PubmedDocsumPage +Library pubmed.PubmedArticlePage + +*** Test Cases *** +When a user searches Google for a term, the first result page's title should contain the search term + Open Pubmed + Search For cat + Click Result On Pubmed Docsum Page 1 + Pubmed Article Page Body Should Contain cat + [Teardown] Close Pubmed Article Page From 733091b95bf8f7f2323322d7705039b6c04149db Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:56:16 -0500 Subject: [PATCH 06/17] Deleted old google page --- demo/test_google.txt | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100755 demo/test_google.txt diff --git a/demo/test_google.txt b/demo/test_google.txt deleted file mode 100755 index 188747f..0000000 --- a/demo/test_google.txt +++ /dev/null @@ -1,14 +0,0 @@ -*** Settings *** -Documentation My first IFT tests -... -Library google.GoogleHomePage -Library google.GoogleSearchResultPage -Library google.DestinationPage - -*** Test Cases *** -When a user searches Google for a term, the first result page's title should contain the search term - Open Google - Search For cat - Click Result On Google Search Result Page 1 - Destination Page Title Should Contain cat - [Teardown] Close Destination Page From 9f7dcec8bd1a3ab181ec900c2d9881ef9522d1d4 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 11:59:08 -0500 Subject: [PATCH 07/17] Modified README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index bfd98c4..7b8539f 100755 --- a/README.md +++ b/README.md @@ -13,6 +13,11 @@ Python [unittest](https://docs.python.org/2/library/unittest.html) test cases. $ pip install robotframework-pageobjects + +## Demo + +Check out and run the [demo](https://github.com/ncbi/robotframework-pageobjects/tree/master/demo). + ## How it Works Here's a Robot test case using some page objects written using the `Page` base class. We need to import any page objects libraries we need in our test From 434bf703a5d92dfe3ed04d2aa335e59a0869cdc7 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 12:01:27 -0500 Subject: [PATCH 08/17] Added a little more text to README. --- demo/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/demo/README.md b/demo/README.md index f8e26e5..dd273e3 100755 --- a/demo/README.md +++ b/demo/README.md @@ -8,6 +8,7 @@ in Robot and outside of Robot. How to run the demo -------------------- +1. Create a virtual environment, then 1. pip install robotframeworkpageobjects 2. $ pybot -vbrowser:firefox -vbaseurl:http://www.ncbi.nlm.nih.gov test_pubmed.robot @@ -16,7 +17,4 @@ $ export PO_BASURL=http://www.ncbi.nlm.nih.gov $ export PO_BROWSER=firefox $ python test_pubmed.py -To run the unittest example in Firefox, set the browser environment variable: -$ export PO_BASURL=http://www.google.com -$ export PO_BROWSERL=firefox -$ python test_pubmed.py +By default tests will run in PhantomJS unless you specify otherwise. From 24bcfb81ac6dcac4d774ff994a7bb6f79da795e9 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 12:04:27 -0500 Subject: [PATCH 09/17] Changed titles of tests --- demo/test_pubmed.py | 2 +- demo/test_pubmed.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/test_pubmed.py b/demo/test_pubmed.py index 9f9ee51..589fdee 100755 --- a/demo/test_pubmed.py +++ b/demo/test_pubmed.py @@ -8,7 +8,7 @@ def setUp(self): self.pubmed_homepage = PubmedHomePage() self.pubmed_homepage.open() - def test_first_result_page_title_should_contain_search_term(self): + def test_first_result_page_body_should_contain_search_term(self): pubmed_docsum_page = self.pubmed_homepage.search_for("cat") self.article_page = pubmed_docsum_page.click_result(1) self.article_page.body_should_contain("cat") diff --git a/demo/test_pubmed.txt b/demo/test_pubmed.txt index 08cfdaf..a263de9 100755 --- a/demo/test_pubmed.txt +++ b/demo/test_pubmed.txt @@ -6,7 +6,7 @@ Library pubmed.PubmedDocsumPage Library pubmed.PubmedArticlePage *** Test Cases *** -When a user searches Google for a term, the first result page's title should contain the search term +When a user searches Google for a term, the first result page's body should contain the search term Open Pubmed Search For cat Click Result On Pubmed Docsum Page 1 From 24e95f1df5e356c5de5aba6aced6bee81b082de8 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 13:01:27 -0500 Subject: [PATCH 10/17] Corrected uri_template --- demo/README.md | 2 +- demo/pubmed.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/README.md b/demo/README.md index dd273e3..26d010e 100755 --- a/demo/README.md +++ b/demo/README.md @@ -13,7 +13,7 @@ How to run the demo 2. $ pybot -vbrowser:firefox -vbaseurl:http://www.ncbi.nlm.nih.gov test_pubmed.robot To run the Python unittest example: -$ export PO_BASURL=http://www.ncbi.nlm.nih.gov +$ export PO_BASEURL=http://www.ncbi.nlm.nih.gov $ export PO_BROWSER=firefox $ python test_pubmed.py diff --git a/demo/pubmed.py b/demo/pubmed.py index 04baa82..ddf4124 100755 --- a/demo/pubmed.py +++ b/demo/pubmed.py @@ -35,7 +35,7 @@ class PubmedDocsumPage(Page): """Models a Pubmed search result page. For example: http://www.ncbi.nlm.nih.gov/pubmed?term=cat """ - uri_template = "/pubmed/?term={term}" + uri = "/pubmed/?term={term}" selectors = { "nth result link": "xpath=(//div[@class='rslt'])[{n}]/p/a", @@ -49,7 +49,7 @@ def click_result(self, i): class PubmedArticlePage(Page): - uri_template = "/pubmed/{article_id}" + uri = "/pubmed/{article_id}" @robot_alias("__name__body_should_contain") def body_should_contain(self, str, ignore_case=True): From ba061806b7c13b7f6dff24d5bea1dbbf303ad7b6 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:10:33 -0500 Subject: [PATCH 11/17] Updated README --- README.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7b8539f..808e531 100755 --- a/README.md +++ b/README.md @@ -18,28 +18,27 @@ Python [unittest](https://docs.python.org/2/library/unittest.html) test cases. Check out and run the [demo](https://github.com/ncbi/robotframework-pageobjects/tree/master/demo). -## How it Works +## How the demo works Here's a Robot test case using some page objects written using the `Page` base class. We need to import any page objects libraries we need in our test case. **Note**: The `Page` class inherits from Selenium2Library, so all methods (keywords) in Selenium2Library are available in your tests, and from `self` from within one of your page objects. -*test_google.robot*: +*test_pubmed.txt*: *** Settings *** - - Documentation Tests searching Google and ending up on Apple. + Documentation My first IFT tests ... - Library google.Page - Library google.ResultPage - + Library pubmed.PubmedHomePage + Library pubmed.PubmedDocsumPage + Library pubmed.PubmedArticlePage + *** Test Cases *** - - Test Google To Apple - Open Google - Search Google For Apple Computers - On Google Result Page Click Result 1 - Title Should Be Apple - [Teardown] Close Google + When a user searches Google for a term, the first result page's body should contain the search term + Open Pubmed + Search For cat + Click Result On Pubmed Docsum Page 1 + Pubmed Article Page Body Should Contain cat + [Teardown] Close Pubmed Article Page This shows you can write the same test, using the same page object libraries outside of Robot, using, for example, Python's unittest module: From b690a1baa8ede3b33ef881125229991895fb9ad7 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:12:01 -0500 Subject: [PATCH 12/17] Corrected --- README.md | 2 +- demo/test_pubmed.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 808e531..0694e62 100755 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ case. **Note**: The `Page` class inherits from Selenium2Library, so all methods Library pubmed.PubmedArticlePage *** Test Cases *** - When a user searches Google for a term, the first result page's body should contain the search term + When a user searches Pubmed for a term, the first result page's body should contain the search term Open Pubmed Search For cat Click Result On Pubmed Docsum Page 1 diff --git a/demo/test_pubmed.txt b/demo/test_pubmed.txt index a263de9..0e41872 100755 --- a/demo/test_pubmed.txt +++ b/demo/test_pubmed.txt @@ -6,7 +6,7 @@ Library pubmed.PubmedDocsumPage Library pubmed.PubmedArticlePage *** Test Cases *** -When a user searches Google for a term, the first result page's body should contain the search term +When a user searches Pubmed for a term, the first result page's body should contain the search term Open Pubmed Search For cat Click Result On Pubmed Docsum Page 1 From d58e7457556855979198754ebc3d4b1023ddf223 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:14:08 -0500 Subject: [PATCH 13/17] More corrections --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0694e62..25782bb 100755 --- a/README.md +++ b/README.md @@ -42,25 +42,26 @@ case. **Note**: The `Page` class inherits from Selenium2Library, so all methods This shows you can write the same test, using the same page object libraries outside of Robot, using, for example, Python's unittest module: + from pubmed import PubmedHomePage import unittest - import google - class TestGoogleSearch(unittest.TestCase): + class PubmedTestCase(unittest.TestCase): def setUp(self): - self.google_page = google.Page().open() + self.pubmed_homepage = PubmedHomePage() + self.pubmed_homepage.open() - def test_google_search_to_apple(self): - result_page = self.google_page.search("apple computers") - result_page.click_result(1) - result_page.title_should_be("Apple") + def test_first_result_page_body_should_contain_search_term(self): + pubmed_docsum_page = self.pubmed_homepage.search_for("cat") + self.article_page = pubmed_docsum_page.click_result(1) + self.article_page.body_should_contain("cat") def tearDown(self): - self.google_page.close() - - unittest.main() + self.article_page.close() + if __name__ == "__main__": + unittest.main() Now we need an actual Google Robot library to make the test work: From 4c2ac393774c4da8b38970b55ce3bab0d4e401d7 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:16:44 -0500 Subject: [PATCH 14/17] Adding more corrections --- README.md | 89 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 25782bb..a0ed6a3 100755 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ case. **Note**: The `Page` class inherits from Selenium2Library, so all methods Pubmed Article Page Body Should Contain cat [Teardown] Close Pubmed Article Page -This shows you can write the same test, using the same page object libraries outside of Robot, using, for example, Python's unittest module: +This shows you can write the same test, using the same page object libraries outside of Robot, using, for example, Python's unittest module. *test_google.py*: from pubmed import PubmedHomePage import unittest @@ -63,66 +63,73 @@ This shows you can write the same test, using the same page object libraries out if __name__ == "__main__": unittest.main() -Now we need an actual Google Robot library to make the test work: +Now we need an actual pubmed page objects to make the test work: -*google.py*: +*pubmed.py*: from robotpageobjects import Page, robot_alias + from robot.utils import asserts - class GooglePage(Page): + class PubmedHomePage(Page): + """ Models the Pubmed home page at: + HOST://ncbi.nlm.nih.gov/pubmed""" - """ - Base Google Page + name = "Pubmed" + uri = "/pubmed" - """ - uri = "/" - - # name attribute tells Robot Keywords what name to put - # after the defined method. So, def foo.. aliases to "Foo Google". - # If no name is defined, the name will be the name of the page object - # class, in this case `Page`. - name = "Google" - - # selectors dictionary is an inheritable dictionary - # mapping names to Selenium2Library locators. selectors = { - "search input": "xpath=//input[@name='q']", - "search button: "id=gbqfba", + "search input": "id=term", + "search button": "id=search", } - def search(self, term): - self.input_text("search input", term) - self.click_element("search button") - return ResultPage() -**Note**: You must return *something* from public (non-underscored) page object methods: either a value from a getter method or a page object instance from non-getter methods. Remember, when you navigate to a new page by clicking a link, submitting a form etc. you should return the appropriate page object. + @robot_alias("type_in__name__search_box") + def type_in_search_box(self, txt): + self.input_text("search input", txt) + return self -Now we want to code a Google search result page. Here's the Google Result page object: + @robot_alias("click__name__search_button") + def click_search_button(self): + self.click_button("search button") + return PubmedDocsumPage() + + @robot_alias("search__name__for") + def search_for(self, term): + self.type_in_search_box(term) + return self.click_search_button() -*google.py*: - ... - class ResultPage(Page): + class PubmedDocsumPage(Page): + """Models a Pubmed search result page. For example: + http://www.ncbi.nlm.nih.gov/pubmed?term=cat """ - """ - A Google Result page. Inherits from Google Page. - """ - # Google uses ajax requests for their searches. - uri = "/#q=cat" + uri = "/pubmed/?term={term}" - name = "Google Result Page" + selectors = { + "nth result link": "xpath=(//div[@class='rslt'])[{n}]/p/a", + } + @robot_alias("click_result_on__name__") def click_result(self, i): - # Calling resolve_selector fills in the "n" variable in - # the selector template at-run-time for the "nth selector link". - # We need to cast the 'i' method parameter to an 'int' because Robot passes - # in all keyword parameters as strings. locator = self.resolve_selector("nth result link", n=int(i)) - - # Now, we pass the resolved locator to the inherited click_link method. self.click_link(locator) - return Page() + return PubmedArticlePage() + + class PubmedArticlePage(Page): + + uri = "/pubmed/{article_id}" + + @robot_alias("__name__body_should_contain") + def body_should_contain(self, str, ignore_case=True): + ref_str = str.lower() if ignore_case else str + ref_str = ref_str.encode("utf-8") + body_txt = self.get_text("css=body").encode("utf-8").lower() + asserts.assert_true(ref_str in body_txt, "body text does not contain %s" %ref_str) + return self + + +**Note**: You must return *something* from public (non-underscored) page object methods: either a value from a getter method or a page object instance from non-getter methods. Remember, when you navigate to a new page by clicking a link, submitting a form etc. you should return the appropriate page object. ## Setting Options From 60bedb80efbe29f7be84cc8aecdab028ad1125e3 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:18:14 -0500 Subject: [PATCH 15/17] Corrections --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a0ed6a3..d116c72 100755 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ Now we need an actual pubmed page objects to make the test work: **Note**: You must return *something* from public (non-underscored) page object methods: either a value from a getter method or a page object instance from non-getter methods. Remember, when you navigate to a new page by clicking a link, submitting a form etc. you should return the appropriate page object. +The rest of this README explains many more details around writing page objects and putting them to work in tests. + ## Setting Options ### Built-in options for `Page` From 56524a89c99024b013e30e6956d76bc6ae326543 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:19:26 -0500 Subject: [PATCH 16/17] Changed .robot to .txt. --- demo/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/README.md b/demo/README.md index 26d010e..c6ae591 100755 --- a/demo/README.md +++ b/demo/README.md @@ -10,7 +10,7 @@ How to run the demo 1. Create a virtual environment, then 1. pip install robotframeworkpageobjects -2. $ pybot -vbrowser:firefox -vbaseurl:http://www.ncbi.nlm.nih.gov test_pubmed.robot +2. $ pybot -vbrowser:firefox -vbaseurl:http://www.ncbi.nlm.nih.gov test_pubmed.txt To run the Python unittest example: $ export PO_BASEURL=http://www.ncbi.nlm.nih.gov From 07b6e21e95967f2125ea204aa0ee078f6d4e8442 Mon Sep 17 00:00:00 2001 From: cohenaa Date: Mon, 24 Nov 2014 15:52:28 -0500 Subject: [PATCH 17/17] Annoated the pubmed page objects with comments. --- demo/pubmed.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/demo/pubmed.py b/demo/pubmed.py index ddf4124..94ed9fb 100755 --- a/demo/pubmed.py +++ b/demo/pubmed.py @@ -6,23 +6,46 @@ class PubmedHomePage(Page): """ Models the Pubmed home page at: HOST://ncbi.nlm.nih.gov/pubmed""" + + # Allows us to call this page + # something other than the default "Pubmed Home Page" + # at the end of keywords. name = "Pubmed" + + # This page is found at baseurl + "/pubmed" uri = "/pubmed" + # inheritable dictionary mapping human-readable names + # to Selenium2Library locators. You can then pass in the + # keys to Selenium2Library actions instead of the locator + # strings. selectors = { "search input": "id=term", "search button": "id=search", } + # Use robot_alias and the "__name__" token to customize + # where to insert the optional page object name + # when calling this keyword. Without the "__name__" + # token this method would map to either "Type In Search Box", + # or "Type In Search Box Pubmed". Using "__name__" we can call + # "Type in Pubmed Search Box foo". @robot_alias("type_in__name__search_box") def type_in_search_box(self, txt): self.input_text("search input", txt) + + # We always return something from a page object, + # even if it's the same page object instance we are + # currently on. return self @robot_alias("click__name__search_button") def click_search_button(self): self.click_button("search button") + + # When navigating to another type of page, return + # the appropriate page object. return PubmedDocsumPage() @robot_alias("search__name__for") @@ -37,12 +60,17 @@ class PubmedDocsumPage(Page): uri = "/pubmed/?term={term}" + # This is a "selector template". We are parameterizing the + # nth result in this xpath. We call this from click_result, below. selectors = { "nth result link": "xpath=(//div[@class='rslt'])[{n}]/p/a", } @robot_alias("click_result_on__name__") def click_result(self, i): + + # For selector templates, we need to resolve the selector to the + # locator first, before finding or acting on the element. locator = self.resolve_selector("nth result link", n=int(i)) self.click_link(locator) return PubmedArticlePage()