Can not find any working samples

66 views
Skip to first unread message

Dmytro Makhno

unread,
Jan 31, 2014, 1:12:38 PM1/31/14
to wtfra...@googlegroups.com
Hello,

I'm not ready to pass directly to proposed structure.

I'd like to find out:
- how to get reusable webdriver (Personally I'm going to prepare a decorator, for short tests)
- how sample page works, for example (My next step decorator will also inject pageFactory)

Something like that:

class MyTest(unittest.TestCase):

    @withBrowser() #injects browser to test
    def test_google_landing(self, browser):
        browser.get("http://www.google.com")
        assert browser.title == "Google"


    @withBrowser(named = "browser") #injects browser, 'named' allows to define name of injected variable
    def test_google_search(self, browser):
        browser.get("http://www.google.com") #note same browser is used here
        q = browser.find_element_by_name('q')
        q.send_keys("wtframework")
        q.submit()
        assert "wtframework" in browser.title

    @withGoogleSite()
    def test_paged_google(self, site): #site is page factory injected by decorator
        site.landing.get()
        assert site._browser.title == "Google" #browser is requested by factory, as usually for wtf
        site.landing.search("wtfframework")
        assert site.search.at_page
        assert "wtfframework" in site._browser.title

    @classmethod
    def tearDownClass(cls):
        #all browsers is freed here, in case if reused.
        #if reusebrowser=false, each test closes browser
        pass

    @classmethod
    def setUpClass(cls):
        #any hooks goes here, base_class takes care of it
        pass


But before this, I want something more simple, but working on wtframework.

Thanks in advance,
  Dmytro
  
    

David Lai

unread,
Jan 31, 2014, 4:32:32 PM1/31/14
to
I'm not sure I understand what you want to do by reusing the browser in that way. The order in which the tests runs probably depends more on the function's name than the actual order it is in the Test class itself.  You'll need to use a custom test runner or organize a test suite that forces that order.


There is a setting to reuse a browser in order to reduce startup time of a test by reducing the need to restart the entire browser.  To do this, you can set the setting, 

selenium:
  reusebrowser: true

Then every time you call, WTF_WEBDRIVER_MANAGER.new_driver(), 
It will use the existing browser instance, but delete the cookies and navigate to about:blank.

The code that handles this logic can be found here, if you want to see more of the details of the implementation.



Dmytro Makhno

unread,
Feb 3, 2014, 3:38:07 PM2/3/14
to wtfra...@googlegroups.com
At least I have what I wanted (following code work for me, I just simplified some really specific parts):
class Session(object): #pages factory == site builder
def __init__(self, driver): self.driver = driver def navigateInstance(self, instance): self.driver.get(...) return self.instance_page() def instance_page(self): PageFactory.create_page(InstancePage.InstancePage, self.driver) def skipIfTurnedOff(testcase): if str(WTF_CONFIG_READER.get("selenium.on", False)).lower() not in ("yes", "true", "t", "1"): #need weird conversions to support string env variables as bool name = unicode(type(testcase).__name__) + u"_" + unicode(testcase._testMethodName) raise unittest.SkipTest(name+"skipped due to selenium turned off") def withSessionBrowser(): def wrapper(func): @wraps(func) def wrapped_func(*args, **kwargs): self = args[0] skipIfTurnedOff(self) self.webdriver_manager = WTF_WEBDRIVER_MANAGER driver = WTF_WEBDRIVER_MANAGER.new_driver() capture = CaptureScreenShot.CaptureScreenShot() #almost as watcher if not driver.current_url.startswith(my_props['tenant']): #scala play manipulations driver.get(my_props['tenant']+'/404') cook = platform.auth.cookies['PLAY_SESSION'] driver.add_cookie({'name' :'PLAY_SESSION', 'value': cook}) session = Session(driver) kwargs.update({"session": session}) #magic line to set session try: func(*args, **kwargs) except AssertionError as e: capture.on_test_failure(self, None, e) #I just change format a bit, and do not rely on inheritance from unittest2 raise e except Exception as e: capture.on_test_error(self, None, e) raise e finally: do_and_ignore(lambda: WTF_WEBDRIVER_MANAGER.close_driver()) return wrapped_func return wrapper class MyDummyTest(MyTestCase): #MyTestCase used as simplification @instance(byApplication=name) #injects instance to test param, project specific decorator for api @withSessionBrowser() #as shown above injects session to test param def test_browser(self, instance, session): session.navigateInstance(instance) assert False #to check screenshot ability @instance(byApplication=name) #injects instance to test param def test_without_browser(self, instance): #some asserts with instance assert True
test_browser is uses browser, but test_without_browser doesn't need browser at all.

This is a bit related to https://github.com/wiredrive/wtframework/issues/26 meaning "why I need only WebDriver" without forcing me to use proposed file structure.

If I set WTF_selenium_on=False, I will have only test_without_browser executed and test_browser ignored.

I think this should provide explanation on a bit unusual usage. 
Also, I was driven by "Selenium For Pythonistas"(http://www.youtube.com/watch?v=2OA941RLbmU), especially "Do Not Use Selenium! No, seriously!"

P.S. Btw, what is the philosophy to validate page in constructor?

Regards,
   Dmytro 

David Lai

unread,
Feb 3, 2014, 7:10:29 PM2/3/14
to wtfra...@googlegroups.com
>> Btw, what is the philosophy to validate page in constructor?

A: The idea behind PageObjects as I see it is to maintain a separation of high level (business logic in the test itself) and Page level (low level interactions such as filling in forms, clicking, etc...).
In order to do this, a PageObject performs 3 basic tasks..
1.) Validate we are indeed on the page we want to be at.
2.) Map UI objects on the page.
3.) Abstract low level individual actions, into higher level business/story level methods.  For example, `.login(username, password)' vs. 3 individual calls to fill in the form fields and click the submit button.

I see Validation as being very important in that we want to be sure we are on the correct page, and not just a different page with the same form elements.  So we would like to validate we are indeed on the correct page when we create that instance of the page object.
Reply all
Reply to author
Forward
0 new messages