I have created an automation framework using toolium with Appium which works for both IOS and Android. Toolium is a python wrapper that I've used to facilitate page object modelling. Basically the UI is separated from the test case so that the same test case can be used across android as well as IOS.
I now need to get the framework working with IOS 10 (With XCUI test framework). So I have changed the elements for IOS so as to support XCUI (Places were XPATH is used and there is no other means of element identification). There is no change in the folder structure/execution mechanism whatsoever. But with the new framework I get an import error from toolium.
Code from tooling mobile page objects.py looks something like this.
# -*- coding: utf-8 -*-
import importlib
from toolium.driver_wrapper import DriverWrappersPool
from toolium.pageobjects.page_object import PageObject
class MobilePageObject(PageObject):
def __new__(cls, driver_wrapper=None):
"""Instantiate android or ios page object from base page object depending on driver configuration
Base, Android and iOS page objects must be defined with following structure:
FOLDER/base/MODULE_NAME.py
class BasePAGE_OBJECT_NAME(MobilePageObject)
FOLDER/android/MODULE_NAME.py
class AndroidPAGE_OBJECT_NAME(BasePAGE_OBJECT_NAME)
FOLDER/ios/MODULE_NAME.py
class IosPAGE_OBJECT_NAME(BasePAGE_OBJECT_NAME)
:param driver_wrapper: driver wrapper instance
:returns: android or ios page object instance
"""
if cls.__name__.startswith('Base'):
__driver_wrapper = driver_wrapper if driver_wrapper else DriverWrappersPool.get_default_wrapper()
__os_name = 'ios' if __driver_wrapper.is_ios_test() else 'android'
__class_name = cls.__name__.replace('Base', __os_name.capitalize())
try:
return getattr(importlib.import_module(cls.__module__), __class_name)(__driver_wrapper)
except AttributeError:
__module_name = cls.__module__.replace('.base.', '.{}.'.format(__os_name))
print __module_name
print __class_name
print __driver_wrapper
return getattr(importlib.import_module(__module_name), __class_name)(__driver_wrapper)
else:
return super(MobilePageObject, cls).__new__(cls)
I follow the folder structure as mentioned in toolium. Basically I have, pageobjects folder under which I have base folder, ios folder and android folder. All my methods are in the base class. The elements are picked up either from the iOS folder or android folder at run time based on the driver type.
Below is the error from the import module
name = 'pageobjects.ios.intro', package = None
def import_module(name, package=None):
"""Import a module.
The 'package' argument is required when performing a relative import. It
specifies the package to use as the anchor point from which to resolve the
relative import to an absolute import.
"""
if name.startswith('.'):
if not package:
raise TypeError("relative imports require the 'package' argument")
level = 0
for character in name:
if character != '.':
break
level += 1
name = _resolve_name(name[level:], package, level)
__import__(name)
E ImportError: No module named ios.intro
When I print the module name and class name this is what I get.
module name = pageobjects.ios.intro
class name = IosIntroduction
intro is one of the modules basically. I access it something like this
from pageobjects.base.intro import BaseIntroduction
On the same machine I have the old framework working without any problem. I have checked environment variables/permissions etc. But I can't seem to figure out as to why the import is failing.
PS: I am running this on MACOSX and also use virtualenvironment for python