Do not match table actions by ordering in integration tests
Instead of this match them by action <a> tag's id, which is composed: * from table name, fixed part and action name for table-level actions and * from row id, fixed part and action name for row-level actions. Doing so may make action names in page objects less readable as they have to be the same as real object name (which are rather terse). Implements blueprint: integration-tests-hardening Change-Id: I3f92ef4cfd098d080199350cbf5e6061aa050907
This commit is contained in:
parent
f6436bbefd
commit
d25d4d2b0d
|
@ -23,7 +23,8 @@ class FlavorsPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
_flavors_table_locator = (by.By.ID, 'flavors')
|
_flavors_table_locator = (by.By.ID, 'flavors')
|
||||||
|
|
||||||
FLAVORS_TABLE_ACTIONS = ("create_flavor", "delete_flavors")
|
FLAVORS_TABLE_NAME = "flavors"
|
||||||
|
FLAVORS_TABLE_ACTIONS = ("create", "delete")
|
||||||
FLAVORS_TABLE_ROW_ACTIONS = {
|
FLAVORS_TABLE_ROW_ACTIONS = {
|
||||||
tables.ComplexActionRowRegion.PRIMARY_ACTION: "edit_flavor",
|
tables.ComplexActionRowRegion.PRIMARY_ACTION: "edit_flavor",
|
||||||
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
||||||
|
@ -47,6 +48,7 @@ class FlavorsPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._flavors_table_locator)
|
src_elem = self._get_element(*self._flavors_table_locator)
|
||||||
return tables.ComplexActionTableRegion(self.driver,
|
return tables.ComplexActionTableRegion(self.driver,
|
||||||
self.conf, src_elem,
|
self.conf, src_elem,
|
||||||
|
self.FLAVORS_TABLE_NAME,
|
||||||
self.FLAVORS_TABLE_ACTIONS,
|
self.FLAVORS_TABLE_ACTIONS,
|
||||||
self.FLAVORS_TABLE_ROW_ACTIONS)
|
self.FLAVORS_TABLE_ROW_ACTIONS)
|
||||||
|
|
||||||
|
@ -61,7 +63,7 @@ class FlavorsPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
def create_flavor(self, name, id_=DEFAULT_ID, vcpus=None, ram=None,
|
def create_flavor(self, name, id_=DEFAULT_ID, vcpus=None, ram=None,
|
||||||
root_disk=None, ephemeral_disk=None, swap_disk=None):
|
root_disk=None, ephemeral_disk=None, swap_disk=None):
|
||||||
self.flavors_table.create_flavor.click()
|
self.flavors_table.create.click()
|
||||||
self.create_flavor_form.name.text = name
|
self.create_flavor_form.name.text = name
|
||||||
if id_ is not None:
|
if id_ is not None:
|
||||||
self.create_flavor_form.flavor_id.text = id_
|
self.create_flavor_form.flavor_id.text = id_
|
||||||
|
@ -76,7 +78,7 @@ class FlavorsPage(basepage.BaseNavigationPage):
|
||||||
def delete_flavor(self, name):
|
def delete_flavor(self, name):
|
||||||
row = self._get_row_with_flavor_name(name)
|
row = self._get_row_with_flavor_name(name)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.flavors_table.delete_flavors.click()
|
self.flavors_table.delete.click()
|
||||||
self.confirm_delete_flavors_form.submit.click()
|
self.confirm_delete_flavors_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ class ProjectsPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
DEFAULT_ENABLED = True
|
DEFAULT_ENABLED = True
|
||||||
PROJECTS_TABLE_NAME_COLUMN_INDEX = 0
|
PROJECTS_TABLE_NAME_COLUMN_INDEX = 0
|
||||||
PROJECTS_TABLE_ACTIONS = ("create_project", "delete_projects")
|
PROJECTS_TABLE_NAME = "tenants"
|
||||||
|
PROJECTS_TABLE_ACTIONS = ("create", "delete")
|
||||||
PROJECTS_TABLE_ROW_ACTIONS = {
|
PROJECTS_TABLE_ROW_ACTIONS = {
|
||||||
tables.ComplexActionRowRegion.PRIMARY_ACTION: "manage_members",
|
tables.ComplexActionRowRegion.PRIMARY_ACTION: "manage_members",
|
||||||
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
||||||
|
@ -58,6 +59,7 @@ class ProjectsPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._projects_table_locator)
|
src_elem = self._get_element(*self._projects_table_locator)
|
||||||
return tables.ComplexActionTableRegion(self.driver,
|
return tables.ComplexActionTableRegion(self.driver,
|
||||||
self.conf, src_elem,
|
self.conf, src_elem,
|
||||||
|
self.PROJECTS_TABLE_NAME,
|
||||||
self.PROJECTS_TABLE_ACTIONS,
|
self.PROJECTS_TABLE_ACTIONS,
|
||||||
self.PROJECTS_TABLE_ROW_ACTIONS
|
self.PROJECTS_TABLE_ROW_ACTIONS
|
||||||
)
|
)
|
||||||
|
@ -94,7 +96,7 @@ class ProjectsPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
def create_project(self, project_name, description=None,
|
def create_project(self, project_name, description=None,
|
||||||
is_enabled=DEFAULT_ENABLED):
|
is_enabled=DEFAULT_ENABLED):
|
||||||
self.projects_table.create_project.click()
|
self.projects_table.create.click()
|
||||||
self.create_project_form.name.text = project_name
|
self.create_project_form.name.text = project_name
|
||||||
if description is not None:
|
if description is not None:
|
||||||
self.create_project_form.description.text = description
|
self.create_project_form.description.text = description
|
||||||
|
@ -106,7 +108,7 @@ class ProjectsPage(basepage.BaseNavigationPage):
|
||||||
def delete_project(self, project_name):
|
def delete_project(self, project_name):
|
||||||
row = self._get_row_with_project_name(project_name)
|
row = self._get_row_with_project_name(project_name)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.projects_table.delete_projects.click()
|
self.projects_table.delete.click()
|
||||||
self.delete_project_submit_button.click()
|
self.delete_project_submit_button.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ class UsersPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
USERS_TABLE_NAME_COLUMN_INDEX = 0
|
USERS_TABLE_NAME_COLUMN_INDEX = 0
|
||||||
|
|
||||||
USERS_TABLE_ACTIONS = ("create_user", "delete_users")
|
USERS_TABLE_NAME = "users"
|
||||||
|
USERS_TABLE_ACTIONS = ("create", "delete")
|
||||||
|
|
||||||
USERS_TABLE_ROW_ACTIONS = {
|
USERS_TABLE_ROW_ACTIONS = {
|
||||||
tables.ComplexActionRowRegion.PRIMARY_ACTION: "edit_user",
|
tables.ComplexActionRowRegion.PRIMARY_ACTION: "edit_user",
|
||||||
|
@ -47,6 +48,7 @@ class UsersPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._users_table_locator)
|
src_elem = self._get_element(*self._users_table_locator)
|
||||||
return tables.ComplexActionTableRegion(self.driver,
|
return tables.ComplexActionTableRegion(self.driver,
|
||||||
self.conf, src_elem,
|
self.conf, src_elem,
|
||||||
|
self.USERS_TABLE_NAME,
|
||||||
self.USERS_TABLE_ACTIONS,
|
self.USERS_TABLE_ACTIONS,
|
||||||
self.USERS_TABLE_ROW_ACTIONS
|
self.USERS_TABLE_ROW_ACTIONS
|
||||||
)
|
)
|
||||||
|
@ -62,7 +64,7 @@ class UsersPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
def create_user(self, name, password,
|
def create_user(self, name, password,
|
||||||
project, role, email=None):
|
project, role, email=None):
|
||||||
self.users_table.create_user.click()
|
self.users_table.create.click()
|
||||||
self.create_user_form.name.text = name
|
self.create_user_form.name.text = name
|
||||||
if email is not None:
|
if email is not None:
|
||||||
self.create_user_form.email.text = email
|
self.create_user_form.email.text = email
|
||||||
|
@ -76,7 +78,7 @@ class UsersPage(basepage.BaseNavigationPage):
|
||||||
def delete_user(self, name):
|
def delete_user(self, name):
|
||||||
row = self._get_row_with_user_name(name)
|
row = self._get_row_with_user_name(name)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.users_table.delete_users.click()
|
self.users_table.delete.click()
|
||||||
self.confirm_delete_users_form.submit.click()
|
self.confirm_delete_users_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ class FloatingipsPage(basepage.BaseNavigationPage):
|
||||||
_floatingips_fadein_popup_locator = (
|
_floatingips_fadein_popup_locator = (
|
||||||
by.By.CSS_SELECTOR, '.alert.alert-success.alert-dismissable.fade.in>p')
|
by.By.CSS_SELECTOR, '.alert.alert-success.alert-dismissable.fade.in>p')
|
||||||
|
|
||||||
FLOATING_IPS_TABLE_ACTIONS = ("allocate_ip_to_project",
|
FLOATING_IPS_TABLE_NAME = 'floating_ips'
|
||||||
"release_floating_ips")
|
FLOATING_IPS_TABLE_ACTIONS = ("allocate", "release")
|
||||||
FLOATING_IPS_TABLE_ROW_ACTION = {
|
FLOATING_IPS_TABLE_ROW_ACTION = {
|
||||||
tables.ComplexActionRowRegion.PRIMARY_ACTION: "associate",
|
tables.ComplexActionRowRegion.PRIMARY_ACTION: "associate",
|
||||||
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: (
|
||||||
|
@ -51,6 +51,7 @@ class FloatingipsPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._floating_ips_table_locator)
|
src_elem = self._get_element(*self._floating_ips_table_locator)
|
||||||
return tables.ComplexActionTableRegion(
|
return tables.ComplexActionTableRegion(
|
||||||
self.driver, self.conf, src_elem,
|
self.driver, self.conf, src_elem,
|
||||||
|
self.FLOATING_IPS_TABLE_NAME,
|
||||||
self.FLOATING_IPS_TABLE_ACTIONS,
|
self.FLOATING_IPS_TABLE_ACTIONS,
|
||||||
self.FLOATING_IPS_TABLE_ROW_ACTION)
|
self.FLOATING_IPS_TABLE_ROW_ACTION)
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ class FloatingipsPage(basepage.BaseNavigationPage):
|
||||||
return forms.BaseFormRegion(self.driver, self.conf, None)
|
return forms.BaseFormRegion(self.driver, self.conf, None)
|
||||||
|
|
||||||
def allocate_floatingip(self):
|
def allocate_floatingip(self):
|
||||||
self.floatingips_table.allocate_ip_to_project.click()
|
self.floatingips_table.allocate.click()
|
||||||
self.floatingip_form.submit.click()
|
self.floatingip_form.submit.click()
|
||||||
ip = re.compile('(([2][5][0-5]\.)|([2][0-4][0-9]\.)'
|
ip = re.compile('(([2][5][0-5]\.)|([2][0-4][0-9]\.)'
|
||||||
+ '|([0-1]?[0-9]?[0-9]\.)){3}(([2][5][0-5])|'
|
+ '|([0-1]?[0-9]?[0-9]\.)){3}(([2][5][0-5])|'
|
||||||
|
@ -73,7 +74,7 @@ class FloatingipsPage(basepage.BaseNavigationPage):
|
||||||
def release_floatingip(self, floatingip):
|
def release_floatingip(self, floatingip):
|
||||||
row = self._get_row_with_floatingip(floatingip)
|
row = self._get_row_with_floatingip(floatingip)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.floatingips_table.release_floating_ips.click()
|
self.floatingips_table.release.click()
|
||||||
self.floatingip_form.submit.click()
|
self.floatingip_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ class KeypairsPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
_key_pairs_table_locator = (by.By.ID, 'keypairs')
|
_key_pairs_table_locator = (by.By.ID, 'keypairs')
|
||||||
|
|
||||||
KEY_PAIRS_TABLE_ACTIONS = ("create_key_pair", "import_key_pair",
|
KEY_PAIRS_TABLE_NAME = "keypairs"
|
||||||
"delete_key_pair")
|
KEY_PAIRS_TABLE_ACTIONS = ("create", "import", "delete")
|
||||||
KEY_PAIRS_TABLE_ROW_ACTION = "delete_key_pair"
|
KEY_PAIRS_TABLE_ROW_ACTION = "delete"
|
||||||
KEY_PAIRS_TABLE_NAME_COLUMN_INDEX = 0
|
KEY_PAIRS_TABLE_NAME_COLUMN_INDEX = 0
|
||||||
|
|
||||||
CREATE_KEY_PAIR_FORM_FIELDS = ('name',)
|
CREATE_KEY_PAIR_FORM_FIELDS = ('name',)
|
||||||
|
@ -44,6 +44,7 @@ class KeypairsPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._key_pairs_table_locator)
|
src_elem = self._get_element(*self._key_pairs_table_locator)
|
||||||
return tables.SimpleActionsTableRegion(self.driver, self.conf,
|
return tables.SimpleActionsTableRegion(self.driver, self.conf,
|
||||||
src_elem,
|
src_elem,
|
||||||
|
self.KEY_PAIRS_TABLE_NAME,
|
||||||
self.KEY_PAIRS_TABLE_ACTIONS,
|
self.KEY_PAIRS_TABLE_ACTIONS,
|
||||||
self.KEY_PAIRS_TABLE_ROW_ACTION)
|
self.KEY_PAIRS_TABLE_ROW_ACTION)
|
||||||
|
|
||||||
|
@ -60,12 +61,12 @@ class KeypairsPage(basepage.BaseNavigationPage):
|
||||||
return bool(self._get_row_with_keypair_name(name))
|
return bool(self._get_row_with_keypair_name(name))
|
||||||
|
|
||||||
def create_keypair(self, keypair_name):
|
def create_keypair(self, keypair_name):
|
||||||
self.keypairs_table.create_key_pair.click()
|
self.keypairs_table.create.click()
|
||||||
self.create_keypair_form.name.text = keypair_name
|
self.create_keypair_form.name.text = keypair_name
|
||||||
self.create_keypair_form.submit.click()
|
self.create_keypair_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
def delete_keypair(self, name):
|
def delete_keypair(self, name):
|
||||||
self._get_row_with_keypair_name(name).delete_key_pair.click()
|
self._get_row_with_keypair_name(name).delete.click()
|
||||||
self.delete_keypair_form.submit.click()
|
self.delete_keypair_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
|
@ -29,7 +29,8 @@ class ImagesPage(basepage.BaseNavigationPage):
|
||||||
|
|
||||||
_images_table_locator = (by.By.ID, 'images')
|
_images_table_locator = (by.By.ID, 'images')
|
||||||
|
|
||||||
IMAGES_TABLE_ACTIONS = ("create_image", "delete_images")
|
IMAGES_TABLE_NAME = "images"
|
||||||
|
IMAGES_TABLE_ACTIONS = ("create", "delete")
|
||||||
IMAGES_TABLE_ROW_ACTIONS = {
|
IMAGES_TABLE_ROW_ACTIONS = {
|
||||||
tables.ComplexActionRowRegion.PRIMARY_ACTION: "launch",
|
tables.ComplexActionRowRegion.PRIMARY_ACTION: "launch",
|
||||||
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: ("create_volume",)
|
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: ("create_volume",)
|
||||||
|
@ -55,6 +56,7 @@ class ImagesPage(basepage.BaseNavigationPage):
|
||||||
src_elem = self._get_element(*self._images_table_locator)
|
src_elem = self._get_element(*self._images_table_locator)
|
||||||
return tables.ComplexActionTableRegion(self.driver,
|
return tables.ComplexActionTableRegion(self.driver,
|
||||||
self.conf, src_elem,
|
self.conf, src_elem,
|
||||||
|
self.IMAGES_TABLE_NAME,
|
||||||
self.IMAGES_TABLE_ACTIONS,
|
self.IMAGES_TABLE_ACTIONS,
|
||||||
self.IMAGES_TABLE_ROW_ACTIONS
|
self.IMAGES_TABLE_ROW_ACTIONS
|
||||||
)
|
)
|
||||||
|
@ -74,7 +76,7 @@ class ImagesPage(basepage.BaseNavigationPage):
|
||||||
image_format=DEFAULT_IMAGE_FORMAT,
|
image_format=DEFAULT_IMAGE_FORMAT,
|
||||||
is_public=DEFAULT_ACCESSIBILITY,
|
is_public=DEFAULT_ACCESSIBILITY,
|
||||||
is_protected=DEFAULT_PROTECTION):
|
is_protected=DEFAULT_PROTECTION):
|
||||||
self.images_table.create_image.click()
|
self.images_table.create.click()
|
||||||
self.create_image_form.name.text = name
|
self.create_image_form.name.text = name
|
||||||
if description is not None:
|
if description is not None:
|
||||||
self.create_image_form.description.text = description
|
self.create_image_form.description.text = description
|
||||||
|
@ -98,7 +100,7 @@ class ImagesPage(basepage.BaseNavigationPage):
|
||||||
def delete_image(self, name):
|
def delete_image(self, name):
|
||||||
row = self._get_row_with_image_name(name)
|
row = self._get_row_with_image_name(name)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.images_table.delete_images.click()
|
self.images_table.delete.click()
|
||||||
self.confirm_delete_images_form.submit.click()
|
self.confirm_delete_images_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class OverviewPage(basepage.BaseNavigationPage):
|
||||||
_usage_table_locator = (by.By.ID, 'project_usage')
|
_usage_table_locator = (by.By.ID, 'project_usage')
|
||||||
_date_form_locator = (by.By.ID, 'date_form')
|
_date_form_locator = (by.By.ID, 'date_form')
|
||||||
|
|
||||||
USAGE_TABLE_ACTIONS = ("download_csv",)
|
USAGE_TABLE_ACTIONS = ("csv_summary",)
|
||||||
|
|
||||||
def __init__(self, driver, conf):
|
def __init__(self, driver, conf):
|
||||||
super(OverviewPage, self).__init__(driver, conf)
|
super(OverviewPage, self).__init__(driver, conf)
|
||||||
|
|
|
@ -65,31 +65,48 @@ class BaseRegion(basewebobject.BaseWebObject):
|
||||||
class _DynamicProperty(object):
|
class _DynamicProperty(object):
|
||||||
"""Serves as new property holder."""
|
"""Serves as new property holder."""
|
||||||
|
|
||||||
def __init__(self, method, index=None, name=None):
|
def __init__(self, method, name=None, id_pattern=None):
|
||||||
"""In case object was created with index != None,
|
"""Invocation of `method` should return either single property, or
|
||||||
it is assumed that the result of self.method should be tuple()
|
a dictionary of properties, or a list of them.
|
||||||
and just certain index should be returned
|
|
||||||
|
In case it's single, neither name, nor id_pattern is required.
|
||||||
|
|
||||||
|
In case it's a dictionary, it's expected that it has a value for
|
||||||
|
the key equal to `name` argument. That's a standard way of
|
||||||
|
fetching a form field).
|
||||||
|
|
||||||
|
In case it's a list, the element with an id equal to the result of
|
||||||
|
`id_pattern % name` is supposed to be there. That's a standard way
|
||||||
|
of fetching a table action (either table-wise or row-wise).
|
||||||
"""
|
"""
|
||||||
self.method = method
|
self.method = method
|
||||||
self.index = index
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.id_pattern = id_pattern
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
result = self.method()
|
result = self.method()
|
||||||
if isinstance(result, dict):
|
if self.name is None:
|
||||||
return result if self.name is None else result[self.name]
|
return result
|
||||||
else:
|
else:
|
||||||
return result if self.index is None else result[self.index]
|
if isinstance(result, list) and self.id_pattern is not None:
|
||||||
|
# NOTE(tsufiev): map table actions to action names using
|
||||||
|
# action tag's ids
|
||||||
|
actual_id = self.id_pattern % self.name
|
||||||
|
result = {self.name: entry for entry in result
|
||||||
|
if entry.get_attribute('id') == actual_id}
|
||||||
|
if isinstance(result, dict):
|
||||||
|
return result[self.name]
|
||||||
|
return result
|
||||||
|
|
||||||
def _init_dynamic_properties(self, new_attr_names, method):
|
def _init_dynamic_properties(self, new_attr_names, method,
|
||||||
|
id_pattern=None):
|
||||||
"""Create new object's 'properties' at runtime."""
|
"""Create new object's 'properties' at runtime."""
|
||||||
for index, new_attr_name in enumerate(new_attr_names):
|
for new_attr_name in new_attr_names:
|
||||||
self._init_dynamic_property(new_attr_name, method, index)
|
self._init_dynamic_property(new_attr_name, method, id_pattern)
|
||||||
|
|
||||||
def _init_dynamic_property(self, new_attr_name, method, index=None):
|
def _init_dynamic_property(self, new_attr_name, method, id_pattern=None):
|
||||||
"""Create new object's property at runtime. If index argument is
|
"""Create new object's property at runtime. See _DynamicProperty's
|
||||||
supplied it is assumed that method returns tuple() and only element
|
__init__ docstring for a description of arguments.
|
||||||
on ${index} position is returned.
|
|
||||||
"""
|
"""
|
||||||
if (new_attr_name in dir(self) or
|
if (new_attr_name in dir(self) or
|
||||||
new_attr_name in self._dynamic_properties):
|
new_attr_name in self._dynamic_properties):
|
||||||
|
@ -97,8 +114,8 @@ class BaseRegion(basewebobject.BaseWebObject):
|
||||||
"The new property could not be "
|
"The new property could not be "
|
||||||
"created." % (self.__class__.__name__,
|
"created." % (self.__class__.__name__,
|
||||||
new_attr_name))
|
new_attr_name))
|
||||||
new_method = self.__class__._DynamicProperty(method, index,
|
new_method = self.__class__._DynamicProperty(
|
||||||
new_attr_name)
|
method, new_attr_name, id_pattern)
|
||||||
inst_method = types.MethodType(new_method, self)
|
inst_method = types.MethodType(new_method, self)
|
||||||
self._dynamic_properties[new_attr_name] = inst_method
|
self._dynamic_properties[new_attr_name] = inst_method
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,6 @@ class FormRegion(BaseFormRegion):
|
||||||
_header_locator = (by.By.CSS_SELECTOR, 'div.modal-header > h3')
|
_header_locator = (by.By.CSS_SELECTOR, 'div.modal-header > h3')
|
||||||
_side_info_locator = (by.By.CSS_SELECTOR, 'div.right')
|
_side_info_locator = (by.By.CSS_SELECTOR, 'div.right')
|
||||||
_fields_locator = (by.By.CSS_SELECTOR, 'fieldset > div.form-group')
|
_fields_locator = (by.By.CSS_SELECTOR, 'fieldset > div.form-group')
|
||||||
_input_locator = (by.By.CSS_SELECTOR, 'input,select,textarea')
|
|
||||||
|
|
||||||
# private methods
|
# private methods
|
||||||
def __init__(self, driver, conf, src_elem, form_field_names):
|
def __init__(self, driver, conf, src_elem, form_field_names):
|
||||||
|
|
|
@ -45,10 +45,13 @@ class BtnActionRowRegion(BaseActionRowRegion):
|
||||||
def __init__(self, driver, conf, src_elem, action_name):
|
def __init__(self, driver, conf, src_elem, action_name):
|
||||||
super(BtnActionRowRegion, self).__init__(driver, conf, src_elem)
|
super(BtnActionRowRegion, self).__init__(driver, conf, src_elem)
|
||||||
self.action_name = action_name
|
self.action_name = action_name
|
||||||
|
self._action_id_pattern = ("%s__action_%%s" %
|
||||||
|
src_elem.get_attribute('id'))
|
||||||
self._init_action()
|
self._init_action()
|
||||||
|
|
||||||
def _init_action(self):
|
def _init_action(self):
|
||||||
self._init_dynamic_property(self.action_name, self._get_action)
|
self._init_dynamic_property(self.action_name, self._get_action,
|
||||||
|
self._action_id_pattern)
|
||||||
|
|
||||||
def _get_action(self):
|
def _get_action(self):
|
||||||
return self._get_element(*self._action_locator)
|
return self._get_element(*self._action_locator)
|
||||||
|
@ -78,15 +81,19 @@ class ComplexActionRowRegion(BaseActionRowRegion):
|
||||||
try:
|
try:
|
||||||
self.primary_action_name = action_names[self.PRIMARY_ACTION]
|
self.primary_action_name = action_names[self.PRIMARY_ACTION]
|
||||||
self.secondary_action_names = action_names[self.SECONDARY_ACTIONS]
|
self.secondary_action_names = action_names[self.SECONDARY_ACTIONS]
|
||||||
|
self._action_id_pattern = ("%s__action_%%s" %
|
||||||
|
src_elem.get_attribute('id'))
|
||||||
self._init_actions()
|
self._init_actions()
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
raise AttributeError(self.ACTIONS_ERROR_MSG)
|
raise AttributeError(self.ACTIONS_ERROR_MSG)
|
||||||
|
|
||||||
def _init_actions(self):
|
def _init_actions(self):
|
||||||
self._init_dynamic_property(self.primary_action_name,
|
self._init_dynamic_property(self.primary_action_name,
|
||||||
self._get_primary_action)
|
self._get_primary_action,
|
||||||
|
self._action_id_pattern)
|
||||||
self._init_dynamic_properties(self.secondary_action_names,
|
self._init_dynamic_properties(self.secondary_action_names,
|
||||||
self._get_secondary_actions)
|
self._get_secondary_actions,
|
||||||
|
self._action_id_pattern)
|
||||||
|
|
||||||
def _get_primary_action(self):
|
def _get_primary_action(self):
|
||||||
return self._get_element(*self._primary_action_locator)
|
return self._get_element(*self._primary_action_locator)
|
||||||
|
@ -182,8 +189,9 @@ class ActionsTableRegion(BasicTableRegion):
|
||||||
' div.table_actions > a')
|
' div.table_actions > a')
|
||||||
|
|
||||||
# private methods
|
# private methods
|
||||||
def __init__(self, driver, conf, src_elm, action_names):
|
def __init__(self, driver, conf, src_elm, table_name, action_names):
|
||||||
super(ActionsTableRegion, self).__init__(driver, conf, src_elm)
|
super(ActionsTableRegion, self).__init__(driver, conf, src_elm)
|
||||||
|
self._action_id_pattern = "%s__action_%%s" % table_name
|
||||||
self.action_names = action_names
|
self.action_names = action_names
|
||||||
self._init_actions()
|
self._init_actions()
|
||||||
|
|
||||||
|
@ -192,7 +200,8 @@ class ActionsTableRegion(BasicTableRegion):
|
||||||
"""Create new methods that corresponds to picking table's
|
"""Create new methods that corresponds to picking table's
|
||||||
action buttons.
|
action buttons.
|
||||||
"""
|
"""
|
||||||
self._init_dynamic_properties(self.action_names, self._get_actions)
|
self._init_dynamic_properties(self.action_names, self._get_actions,
|
||||||
|
self._action_id_pattern)
|
||||||
|
|
||||||
def _get_actions(self):
|
def _get_actions(self):
|
||||||
return self._get_elements(*self._actions_locator)
|
return self._get_elements(*self._actions_locator)
|
||||||
|
@ -206,9 +215,10 @@ class ActionsTableRegion(BasicTableRegion):
|
||||||
class SimpleActionsTableRegion(ActionsTableRegion):
|
class SimpleActionsTableRegion(ActionsTableRegion):
|
||||||
"""Table which rows has buttons in action column."""
|
"""Table which rows has buttons in action column."""
|
||||||
|
|
||||||
def __init__(self, driver, conf, src_elm, action_names, row_action_name):
|
def __init__(self, driver, conf, src_elm, table_name, action_names,
|
||||||
super(SimpleActionsTableRegion, self).__init__(driver, conf, src_elm,
|
row_action_name):
|
||||||
action_names)
|
super(SimpleActionsTableRegion, self).__init__(
|
||||||
|
driver, conf, src_elm, table_name, action_names)
|
||||||
self.row_action_name = row_action_name
|
self.row_action_name = row_action_name
|
||||||
|
|
||||||
def _get_rows(self):
|
def _get_rows(self):
|
||||||
|
@ -222,9 +232,10 @@ class SimpleActionsTableRegion(ActionsTableRegion):
|
||||||
class ComplexActionTableRegion(ActionsTableRegion):
|
class ComplexActionTableRegion(ActionsTableRegion):
|
||||||
"""Table which has button and selectbox in the action column."""
|
"""Table which has button and selectbox in the action column."""
|
||||||
|
|
||||||
def __init__(self, driver, conf, src_elm, action_names, row_action_names):
|
def __init__(self, driver, conf, src_elm, table_name,
|
||||||
super(ComplexActionTableRegion, self).__init__(driver, conf, src_elm,
|
action_names, row_action_names):
|
||||||
action_names)
|
super(ComplexActionTableRegion, self).__init__(
|
||||||
|
driver, conf, src_elm, table_name, action_names)
|
||||||
self.row_action_names = row_action_names
|
self.row_action_names = row_action_names
|
||||||
|
|
||||||
def _get_rows(self):
|
def _get_rows(self):
|
||||||
|
|
Loading…
Reference in New Issue