Reputation: 1214
I am creating a RobotFramework library with three different classes. I am able to use the first class keywords, however I am not able to use the two remaining classes keywords. As per RF documentation I tried to use import as follow LibraryName.className And I am also setting python Path to my personal library’s folder. However when running tests only first class keyword are recognised. I have tried to change the name of my first class to a different name then my lib file and import each class separately but that did not work for the three class’s keywords.
Here is my Lib code :
from robotpageobjects import Page, robot_alias
from robot.utils import asserts
class HomePage(Page):
""" Models WeekendDesk home page at:
HOST:weekendesk.fr/"""
name="Home"
# This is Then Keyword for Weekendesk Home Page.
# This page is found at baseurl"
uri = ""
# 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 = {
"destination": "id=concatField",
"search button": "id=searchButton",
"arrival date": "id=spArrival",
"departure date": "id=spDeparture",
}
# 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 WDHomePage". Using "__name__" we can call
# "Type in Home Search Box foo".
@robot_alias("type_in__name__search_box")
def type_in_search_box(self, txt):
self.input_text("destination", 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("type_in__name__arrival_box")
def type_in_arrival_box(self, txt):
self.input_text("arrival date", 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("type_in__name__departure_box")
def type_in_departure_box(self, txt):
self.input_text("departure date", 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_link("search button")
return SerpPage()
@robot_alias("search_weekends_for")
def search_for(self, concatField,spArrival,spDeparture):
self.type_in_search_box(concatField)
self.type_in_arrival_box(spArrival)
self.type_in_departure_box(spDeparture)
return self.click_search_button()
class SerpPage(Page):
"""Models a Serp search result page. For example:
http://www.weekendesk.fr/sejour/DTE6_070815RGN1_iPLC2_3iNGH1_5VRS1_9 /weekend-en-PACA """
# The URI for the SERP page does not have a template to follow
uri = ""
Name= "Serp"
# 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": "div.searchResult:nth-child(1) > div:nth-child(1) > h2:nth-child(1) > a:nth-child(1)"
}
@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 ProductPage()
class ProductPage(Page):
uri = ""
Name="Product"
@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
My Lib file name is HomePage.py
Thanks
Upvotes: 2
Views: 3238
Reputation: 1354
What you're asking to do should be possible, however, without seeing your robot test suite, it's not really clear what you're actually doing. For example, if your library file is on the PYTHONPATH, you can import the classes individually. For example, if this was your library file, I called mine LibTest.py
:
from robot.api import logger
class LibTest:
def libtest_1(self):
logger.warn("In LibTest")
class OtherTest:
def othertest_1(self):
logger.warn("In OtherTest")
class OneMoreTest:
def onemoretest_1(self):
logger.warn("In OneMoreTest")
Then in your Test Suite, you can load the classes individually:
*** Settings ***
Library LibTest.LibTest
Library LibTest.OtherTest
Library LibTest.OneMoreTest
*** Test Cases ***
sometest
Log Test Start
libtest_1
othertest_1
onemoretest_1
This example works on my environment: Python 2.7.6 with Robot Framework 2.8.7. Here is the console I output I get:
20150831 12:48:49.449 : INFO : Test Start
20150831 12:48:49.450 : WARN : In LibTest
20150831 12:48:49.450 : WARN : In OtherTest
20150831 12:48:49.451 : WARN : In OneMoreTest
I think Robot, though, is really trying to encourage you to keep your library classes in separate files - as it's a little bit easier to deal with, i.e., you don't need to put them on the PYTHONPATH.
Upvotes: 2