Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- New nav_base method named ele_wait_value #untracked
- Move dropdown methods to new control dropdown class #258
- Added new class named 'ControlTable' #248
- Add coverage tests for function: driver_name_filter #268

### Changed
- Separate benchmark test from all functional tests at tox -e coverage #251
Expand All @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Now get_text check for input tag #untracked
- Function with Cognitive Complexity of 13 (exceeds 5 allowed) #265
- New internal method to reduce duplication at ControlDropdown #untracked
- Fix similar code at #271

### Fixed
- Can't use dropdown methods if ControlForm strict_tags is disabled #247
Expand All @@ -32,6 +34,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Removed
- Deleted ControlGroup + tests #256
- Deleted controls property named 'on_instance_load' #259
- Deleted opera support #270

## [v0.6.0] - 2019-03-18

Expand Down
6 changes: 1 addition & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,7 @@ Configuration File
"iexplorerdriver_32.exe",
"iexplorerdriver_64.exe",
"edgedriver_32.exe",
"edgedriver_64.exe",
"operadriver_32.exe",
"operadriver_64.exe",
"operadriver_32",
"operadriver_64"
"edgedriver_64.exe"
]
}
}
Expand Down
24 changes: 19 additions & 5 deletions USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,7 @@ Have classes for this down package: ``qacode.core.bots``
"iexplorerdriver_32.exe",
"iexplorerdriver_64.exe",
"edgedriver_32.exe",
"edgedriver_64.exe",
"operadriver_32.exe",
"operadriver_64.exe",
"operadriver_32",
"operadriver_64"
"edgedriver_64.exe"
]
}
}
Expand Down Expand Up @@ -156,6 +152,24 @@ ControlDropdown
+ method **deselect** : The Select class only works with tags which have select tags
+ method **deselect_all** : The Select class only works with tags which have select tags with multiple="multiple" attribute.

ControlTable
~~~~~~~~~~~~

- Methods for **ControlTable**

+ method **__check_reload__form__** : Allow to check before methods calls to ensure if it's neccessary reload element properties
+ method **__load_table__** : Allow to load all TR > TD items from a TABLE element
+ method **__load_table_html4__** : Allow to load table with this structure ``TABLE > (TR > TH)+(TR > TD)``
+ method **__load_table_html5__** : Allow to load table with this structure ``TABLE > (THEAD > (TR > TH))+(TBODY > (TR > TH))``
+ method **__get_row__** : Allow to get cells of a <TR> element
+ method **__try__** : Allow to exec some method to handle exception
+ method **reload** : Reload 'self.settings' property:dict and call to instance logic with new configuration

- Properties for **ControlTable**

+ property **table**: GET / SET for table element ( *just a ``WebElement`` based on ``table`` tag*)
+ property **rows**: GET for rows cells based on controls instances

Pages
-----

Expand Down
2 changes: 1 addition & 1 deletion qacode/configs/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"chromedriver_64",
"firefoxdriver_32.exe",
"firefoxdriver_64.exe",
"firefoxdriver_64.exe",
"firefoxdriver_64",
"firefoxdriver_32",
"iexplorerdriver_32.exe",
"iexplorerdriver_64.exe",
Expand Down
63 changes: 15 additions & 48 deletions qacode/core/bots/bot_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.touch_actions import TouchActions
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.opera.options import Options as OperaOptions
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from selenium.webdriver.support.ui import WebDriverWait

Expand Down Expand Up @@ -156,13 +155,23 @@ class instanced for one browser
"firefox": DesiredCapabilities.FIREFOX.copy(),
"iexplorer": DesiredCapabilities.INTERNETEXPLORER.copy(),
"edge": DesiredCapabilities.EDGE.copy(),
"opera": DesiredCapabilities.OPERA.copy(),
}[browser_name]
except KeyError:
msg = 'Bad browser selected at load options'
raise CoreException(msg=msg, log=self.log)
return capabilities

def __check_driver_ready__(self, driver_path, capabilities, options):
"""Some checks to ensure driver path, caps and options
are ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
if options is None:
options = self.curr_options

def get_options(self, browser_name='chrome', headless_enabled=False):
"""Instance Options class from selenium and return it

Expand All @@ -186,7 +195,6 @@ class instanced for one browser
options = {
"chrome": ChromeOptions(),
"firefox": FirefoxOptions(),
"opera": OperaOptions(),
}[browser_name]
if headless_enabled:
options.add_argument("--headless")
Expand Down Expand Up @@ -245,12 +253,7 @@ def get_driver_chrome(self, driver_path=None, capabilities=None,
Returns:
[WebDriver.Chrome] -- WebDriver opened and ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
if options is None:
options = self.curr_options
self.__check_driver_ready__(driver_path, capabilities, options)
return WebDriver.Chrome(
executable_path=driver_path,
desired_capabilities=capabilities,
Expand All @@ -270,12 +273,7 @@ def get_driver_firefox(self, driver_path=None, capabilities=None,
Returns:
[WebDriver.Firefox] -- WebDriver opened and ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
if options is None:
options = self.curr_options
self.__check_driver_ready__(driver_path, capabilities, options)
return WebDriver.Firefox(
executable_path=driver_path,
capabilities=capabilities,
Expand All @@ -293,10 +291,7 @@ def get_driver_iexplorer(self, driver_path=None, capabilities=None):
Returns:
[WebDriver.Ie] -- WebDriver opened and ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
self.__check_driver_ready__(driver_path, capabilities)
return WebDriver.Ie(
executable_path=driver_path,
capabilities=capabilities)
Expand All @@ -314,38 +309,11 @@ def get_driver_edge(self, driver_path=None, capabilities=None):
Returns:
[WebDriver.Edge] -- WebDriver opened and ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
self.__check_driver_ready__(driver_path, capabilities)
return WebDriver.Edge(
executable_path=driver_path,
capabilities=capabilities)

def get_driver_opera(self, driver_path=None, capabilities=None,
options=None):
"""Open WebDriver selenium based on Opera browser

Keyword Arguments:
driver_path {str} -- Path for driver binary path
(default: {None})
capabilities {DesiredCapabilities} -- Capabilities for browser
(default: {None})
options {Options} -- Options for browser (default: {None})

Returns:
[WebDriver.Opera] -- WebDriver opened and ready to be used
"""
if driver_path is None:
driver_path = self.curr_driver_path
if capabilities is None:
capabilities = self.curr_caps
if options is None:
options = self.curr_options
return WebDriver.Opera(
executable_path=driver_path,
capabilities=capabilities)

def mode_local(self, browser_name='chrome'):
"""Open new brower on local mode

Expand All @@ -366,7 +334,6 @@ def mode_local(self, browser_name='chrome'):
"firefox": self.get_driver_firefox(),
"iexplorer": self.get_driver_iexplorer(),
"edge": self.get_driver_edge(),
"opera": self.get_driver_opera(),
}[browser_name]
except KeyError:
raise CoreException(
Expand Down
9 changes: 7 additions & 2 deletions qacode/core/webs/controls/control_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ def __load_table__(self, element=None):
"""Allow to load all TR > TD items from a TABLE element

Before structure some checks are necessary for some children elements:
caption {ControlBase}-- optional <caption> element
tbody {ControlBase}-- required 1 or more <tbody> elements
caption {ControlBase}-- optional <caption> element if tbody found
thead {ControlBase}-- optional <thead> element if tbody found
tfoot {ControlBase}-- optional <tfoot> element if tbody found

Examples:
Use case 1. TABLE > (TR > TH)+(TR > TD)
Expand Down Expand Up @@ -90,7 +93,9 @@ def __load_table_html5__(self):
return rows

def __get_row__(self, ctl_row, selector):
"""WARNING: this method just can be used from __load_table__"""
"""Allow to get cells of a <TR> element
WARNING: this method just can be used from __load_table__
"""
row = []
for cell in ctl_row.find_children(selector):
text = cell.get_text()
Expand Down
62 changes: 39 additions & 23 deletions tests/001_functionals/suite_001_botbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,47 @@ def setup_method(self, test_method):

def teardown_method(self, method):
"""TODO: doc method"""
if method.__name__ == 'test_botbase_drivernamefilter_ok':
return True
self.try_bot_close()

def try_bot_close(self):
"""Utility method for tests"""
try:
if self.bot:
self.bot.close()
except Exception:
print(
"Fail at try to close bot, maybe never opened")
print("ERROR: Failed at try to close bot")

@pytest.mark.skipIf(SKIP, SKIP_MSG)
@pytest.mark.parametrize("is_win", [True, False])
@pytest.mark.parametrize("is_64bits", [True, False])
@pytest.mark.parametrize("browser", ["chrome", "firefox"])
def test_botbase_drivernamefilter_ok(self, browser, is_win, is_64bits):
"""Testcase: test_botbase_drivernamefilter_ok"""
if 'bot' not in dir(self):
settings = SETTINGS.copy()
self.add_property('bot', BotBase(**settings))
# end setup
self.bot.IS_WIN = is_win
self.bot.IS_64BITS = is_64bits
name_formatted = self.bot.driver_name_filter(browser)
if is_win and not is_64bits:
self.assert_equals(
name_formatted, "{}driver_32.exe".format(browser))
if is_win and is_64bits:
self.assert_equals(
name_formatted, "{}driver_64.exe".format(browser))
if not is_win and not is_64bits:
self.assert_equals(
name_formatted, "{}driver_32".format(browser))
if not is_win and is_64bits:
self.assert_equals(
name_formatted, "{}driver_64".format(browser))
self.try_bot_close()

@pytest.mark.parametrize("browser_name", [
"chrome",
"firefox",
"iexplorer",
"edge",
"opera"
])
"chrome", "firefox", "iexplorer", "edge"])
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
def test_bot_modes_and_names(self, driver_mode, browser_name):
"""Testcase: test_001_bot_local_chrome"""
Expand All @@ -57,12 +84,6 @@ def test_bot_modes_and_names(self, driver_mode, browser_name):
pytest.skip(msg="Browser not configured")
if browser_name == 'iexplorer':
browser_name = 'internet explorer'
if browser_name == 'opera':
pytest.skip(
msg=("Issue opened on official opera"
" chromium github: "
"https://github.com/operasoftware"
"/operachromiumdriver/issues/9"))
self.bot = BotBase(**settings)
self.timer(wait=WAIT_TO_CLOSE)
self.assert_is_instance(self.bot, BotBase)
Expand All @@ -72,9 +93,7 @@ def test_bot_modes_and_names(self, driver_mode, browser_name):
self.assert_equals(self.bot.settings.get('mode'), driver_mode)
self.assert_equals(self.bot.curr_caps['browserName'], browser_name)

@pytest.mark.parametrize("browser_name", [
"chrome", "firefox", "opera"
])
@pytest.mark.parametrize("browser_name", ["chrome", "firefox"])
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
def test_bot_modes_headless(self, driver_mode, browser_name):
"""Testcase: test_bot_modes_headless"""
Expand All @@ -86,12 +105,6 @@ def test_bot_modes_headless(self, driver_mode, browser_name):
'mode': str(driver_mode),
'options': {"headless": True}
})
if browser_name == 'opera':
pytest.skip(
msg=("Issue opened on official opera"
" chromium github: "
"https://github.com/operasoftware"
"/operachromiumdriver/issues/9"))
self.bot = BotBase(**settings)
self.timer(wait=WAIT_TO_CLOSE)
self.assert_is_instance(self.bot, BotBase)
Expand All @@ -101,20 +114,23 @@ def test_bot_modes_headless(self, driver_mode, browser_name):
self.assert_equals(self.bot.settings.get('mode'), driver_mode)
self.assert_equals(self.bot.curr_caps['browserName'], browser_name)

@pytest.mark.skipIf(SKIP, SKIP_MSG)
def test_botbase_invalidsettingskey(self):
"""Testcase: test_botbase_invalidsettingskey"""
settings = SETTINGS.copy()
settings.get('bot').update({"must_raises": "test"})
with pytest.raises(CoreException):
BotBase(**settings)

@pytest.mark.skipIf(SKIP, SKIP_MSG)
def test_botbase_invalidmode(self):
"""Testcase: test_botbase_invalidmode"""
settings = SETTINGS.copy()
settings.get('bot').update({"mode": "must_raises"})
with pytest.raises(CoreException):
self.bot = BotBase(**settings)

@pytest.mark.skipIf(SKIP, SKIP_MSG)
def test_botbase_invalidbrowser(self):
"""Testcase: test_botbase_invalidbrowser"""
settings = SETTINGS.copy()
Expand Down
17 changes: 2 additions & 15 deletions tests/002_benchmarks/suite_001_browsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ def bot_benchmark(self, browser_name, driver_mode, is_headless):
pytest.skip(msg="Browser not configured")
if browser_name == 'iexplorer':
browser_name = 'internet explorer'
if browser_name == 'opera':
pytest.skip(
msg=("Issue opened on official opera"
" chromium github: "
"https://github.com/operasoftware"
"/operachromiumdriver/issues/9"))
self.bot = BotBase(**settings)
self.assert_is_instance(self.bot, BotBase)
self.assert_equals(
Expand All @@ -69,12 +63,7 @@ def bot_benchmark(self, browser_name, driver_mode, is_headless):

@pytest.mark.benchmark(group='BROWSERS')
@pytest.mark.parametrize("browser_name", [
"chrome",
"firefox",
"iexplorer",
"edge",
"opera"
])
"chrome", "firefox", "iexplorer", "edge"])
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
@pytest.mark.skipIf(SKIP, SKIP_MSG)
def test_benchmark_browsers(self, benchmark, browser_name, driver_mode):
Expand All @@ -93,9 +82,7 @@ def test_benchmark_browsers(self, benchmark, browser_name, driver_mode):
rounds=ROUNDS)

@pytest.mark.benchmark(group='BROWSERS_HEADLESS')
@pytest.mark.parametrize("browser_name", [
"chrome", "firefox", "opera"
])
@pytest.mark.parametrize("browser_name", ["chrome", "firefox"])
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
@pytest.mark.skipIf(SKIP, SKIP_MSG)
def test_benchmark_browsers_headless(self, benchmark,
Expand Down