Skip to content

Commit dd7de5a

Browse files
authored
[qacode] fix for issue #268 (#269)
* [qacode] fix for issue #268 * [qacode] remove opera support #270 + fix similar code at #271 * [qacode] test imroved for bot from 27secs to 4secs
1 parent 7da1cec commit dd7de5a

File tree

8 files changed

+87
-99
lines changed

8 files changed

+87
-99
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1212
- New nav_base method named ele_wait_value #untracked
1313
- Move dropdown methods to new control dropdown class #258
1414
- Added new class named 'ControlTable' #248
15+
- Add coverage tests for function: driver_name_filter #268
1516

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

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

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

README.rst

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,7 @@ Configuration File
102102
"iexplorerdriver_32.exe",
103103
"iexplorerdriver_64.exe",
104104
"edgedriver_32.exe",
105-
"edgedriver_64.exe",
106-
"operadriver_32.exe",
107-
"operadriver_64.exe",
108-
"operadriver_32",
109-
"operadriver_64"
105+
"edgedriver_64.exe"
110106
]
111107
}
112108
}

USAGE.rst

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ Have classes for this down package: ``qacode.core.bots``
3939
"iexplorerdriver_32.exe",
4040
"iexplorerdriver_64.exe",
4141
"edgedriver_32.exe",
42-
"edgedriver_64.exe",
43-
"operadriver_32.exe",
44-
"operadriver_64.exe",
45-
"operadriver_32",
46-
"operadriver_64"
42+
"edgedriver_64.exe"
4743
]
4844
}
4945
}
@@ -156,6 +152,24 @@ ControlDropdown
156152
+ method **deselect** : The Select class only works with tags which have select tags
157153
+ method **deselect_all** : The Select class only works with tags which have select tags with multiple="multiple" attribute.
158154

155+
ControlTable
156+
~~~~~~~~~~~~
157+
158+
- Methods for **ControlTable**
159+
160+
+ method **__check_reload__form__** : Allow to check before methods calls to ensure if it's neccessary reload element properties
161+
+ method **__load_table__** : Allow to load all TR > TD items from a TABLE element
162+
+ method **__load_table_html4__** : Allow to load table with this structure ``TABLE > (TR > TH)+(TR > TD)``
163+
+ method **__load_table_html5__** : Allow to load table with this structure ``TABLE > (THEAD > (TR > TH))+(TBODY > (TR > TH))``
164+
+ method **__get_row__** : Allow to get cells of a <TR> element
165+
+ method **__try__** : Allow to exec some method to handle exception
166+
+ method **reload** : Reload 'self.settings' property:dict and call to instance logic with new configuration
167+
168+
- Properties for **ControlTable**
169+
170+
+ property **table**: GET / SET for table element ( *just a ``WebElement`` based on ``table`` tag*)
171+
+ property **rows**: GET for rows cells based on controls instances
172+
159173
Pages
160174
-----
161175

qacode/configs/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"chromedriver_64",
1515
"firefoxdriver_32.exe",
1616
"firefoxdriver_64.exe",
17-
"firefoxdriver_64.exe",
17+
"firefoxdriver_64",
1818
"firefoxdriver_32",
1919
"iexplorerdriver_32.exe",
2020
"iexplorerdriver_64.exe",

qacode/core/bots/bot_base.py

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from selenium.webdriver.common.action_chains import ActionChains
1515
from selenium.webdriver.common.touch_actions import TouchActions
1616
from selenium.webdriver.firefox.options import Options as FirefoxOptions
17-
from selenium.webdriver.opera.options import Options as OperaOptions
1817
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
1918
from selenium.webdriver.support.ui import WebDriverWait
2019

@@ -156,13 +155,23 @@ class instanced for one browser
156155
"firefox": DesiredCapabilities.FIREFOX.copy(),
157156
"iexplorer": DesiredCapabilities.INTERNETEXPLORER.copy(),
158157
"edge": DesiredCapabilities.EDGE.copy(),
159-
"opera": DesiredCapabilities.OPERA.copy(),
160158
}[browser_name]
161159
except KeyError:
162160
msg = 'Bad browser selected at load options'
163161
raise CoreException(msg=msg, log=self.log)
164162
return capabilities
165163

164+
def __check_driver_ready__(self, driver_path, capabilities, options):
165+
"""Some checks to ensure driver path, caps and options
166+
are ready to be used
167+
"""
168+
if driver_path is None:
169+
driver_path = self.curr_driver_path
170+
if capabilities is None:
171+
capabilities = self.curr_caps
172+
if options is None:
173+
options = self.curr_options
174+
166175
def get_options(self, browser_name='chrome', headless_enabled=False):
167176
"""Instance Options class from selenium and return it
168177
@@ -186,7 +195,6 @@ class instanced for one browser
186195
options = {
187196
"chrome": ChromeOptions(),
188197
"firefox": FirefoxOptions(),
189-
"opera": OperaOptions(),
190198
}[browser_name]
191199
if headless_enabled:
192200
options.add_argument("--headless")
@@ -245,12 +253,7 @@ def get_driver_chrome(self, driver_path=None, capabilities=None,
245253
Returns:
246254
[WebDriver.Chrome] -- WebDriver opened and ready to be used
247255
"""
248-
if driver_path is None:
249-
driver_path = self.curr_driver_path
250-
if capabilities is None:
251-
capabilities = self.curr_caps
252-
if options is None:
253-
options = self.curr_options
256+
self.__check_driver_ready__(driver_path, capabilities, options)
254257
return WebDriver.Chrome(
255258
executable_path=driver_path,
256259
desired_capabilities=capabilities,
@@ -270,12 +273,7 @@ def get_driver_firefox(self, driver_path=None, capabilities=None,
270273
Returns:
271274
[WebDriver.Firefox] -- WebDriver opened and ready to be used
272275
"""
273-
if driver_path is None:
274-
driver_path = self.curr_driver_path
275-
if capabilities is None:
276-
capabilities = self.curr_caps
277-
if options is None:
278-
options = self.curr_options
276+
self.__check_driver_ready__(driver_path, capabilities, options)
279277
return WebDriver.Firefox(
280278
executable_path=driver_path,
281279
capabilities=capabilities,
@@ -293,10 +291,7 @@ def get_driver_iexplorer(self, driver_path=None, capabilities=None):
293291
Returns:
294292
[WebDriver.Ie] -- WebDriver opened and ready to be used
295293
"""
296-
if driver_path is None:
297-
driver_path = self.curr_driver_path
298-
if capabilities is None:
299-
capabilities = self.curr_caps
294+
self.__check_driver_ready__(driver_path, capabilities)
300295
return WebDriver.Ie(
301296
executable_path=driver_path,
302297
capabilities=capabilities)
@@ -314,38 +309,11 @@ def get_driver_edge(self, driver_path=None, capabilities=None):
314309
Returns:
315310
[WebDriver.Edge] -- WebDriver opened and ready to be used
316311
"""
317-
if driver_path is None:
318-
driver_path = self.curr_driver_path
319-
if capabilities is None:
320-
capabilities = self.curr_caps
312+
self.__check_driver_ready__(driver_path, capabilities)
321313
return WebDriver.Edge(
322314
executable_path=driver_path,
323315
capabilities=capabilities)
324316

325-
def get_driver_opera(self, driver_path=None, capabilities=None,
326-
options=None):
327-
"""Open WebDriver selenium based on Opera browser
328-
329-
Keyword Arguments:
330-
driver_path {str} -- Path for driver binary path
331-
(default: {None})
332-
capabilities {DesiredCapabilities} -- Capabilities for browser
333-
(default: {None})
334-
options {Options} -- Options for browser (default: {None})
335-
336-
Returns:
337-
[WebDriver.Opera] -- WebDriver opened and ready to be used
338-
"""
339-
if driver_path is None:
340-
driver_path = self.curr_driver_path
341-
if capabilities is None:
342-
capabilities = self.curr_caps
343-
if options is None:
344-
options = self.curr_options
345-
return WebDriver.Opera(
346-
executable_path=driver_path,
347-
capabilities=capabilities)
348-
349317
def mode_local(self, browser_name='chrome'):
350318
"""Open new brower on local mode
351319
@@ -366,7 +334,6 @@ def mode_local(self, browser_name='chrome'):
366334
"firefox": self.get_driver_firefox(),
367335
"iexplorer": self.get_driver_iexplorer(),
368336
"edge": self.get_driver_edge(),
369-
"opera": self.get_driver_opera(),
370337
}[browser_name]
371338
except KeyError:
372339
raise CoreException(

qacode/core/webs/controls/control_table.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ def __load_table__(self, element=None):
4343
"""Allow to load all TR > TD items from a TABLE element
4444
4545
Before structure some checks are necessary for some children elements:
46-
caption {ControlBase}-- optional <caption> element
46+
tbody {ControlBase}-- required 1 or more <tbody> elements
47+
caption {ControlBase}-- optional <caption> element if tbody found
48+
thead {ControlBase}-- optional <thead> element if tbody found
49+
tfoot {ControlBase}-- optional <tfoot> element if tbody found
4750
4851
Examples:
4952
Use case 1. TABLE > (TR > TH)+(TR > TD)
@@ -90,7 +93,9 @@ def __load_table_html5__(self):
9093
return rows
9194

9295
def __get_row__(self, ctl_row, selector):
93-
"""WARNING: this method just can be used from __load_table__"""
96+
"""Allow to get cells of a <TR> element
97+
WARNING: this method just can be used from __load_table__
98+
"""
9499
row = []
95100
for cell in ctl_row.find_children(selector):
96101
text = cell.get_text()

tests/001_functionals/suite_001_botbase.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,47 @@ def setup_method(self, test_method):
2828

2929
def teardown_method(self, method):
3030
"""TODO: doc method"""
31+
if method.__name__ == 'test_botbase_drivernamefilter_ok':
32+
return True
33+
self.try_bot_close()
34+
35+
def try_bot_close(self):
36+
"""Utility method for tests"""
3137
try:
3238
if self.bot:
3339
self.bot.close()
3440
except Exception:
35-
print(
36-
"Fail at try to close bot, maybe never opened")
41+
print("ERROR: Failed at try to close bot")
42+
43+
@pytest.mark.skipIf(SKIP, SKIP_MSG)
44+
@pytest.mark.parametrize("is_win", [True, False])
45+
@pytest.mark.parametrize("is_64bits", [True, False])
46+
@pytest.mark.parametrize("browser", ["chrome", "firefox"])
47+
def test_botbase_drivernamefilter_ok(self, browser, is_win, is_64bits):
48+
"""Testcase: test_botbase_drivernamefilter_ok"""
49+
if 'bot' not in dir(self):
50+
settings = SETTINGS.copy()
51+
self.add_property('bot', BotBase(**settings))
52+
# end setup
53+
self.bot.IS_WIN = is_win
54+
self.bot.IS_64BITS = is_64bits
55+
name_formatted = self.bot.driver_name_filter(browser)
56+
if is_win and not is_64bits:
57+
self.assert_equals(
58+
name_formatted, "{}driver_32.exe".format(browser))
59+
if is_win and is_64bits:
60+
self.assert_equals(
61+
name_formatted, "{}driver_64.exe".format(browser))
62+
if not is_win and not is_64bits:
63+
self.assert_equals(
64+
name_formatted, "{}driver_32".format(browser))
65+
if not is_win and is_64bits:
66+
self.assert_equals(
67+
name_formatted, "{}driver_64".format(browser))
68+
self.try_bot_close()
3769

3870
@pytest.mark.parametrize("browser_name", [
39-
"chrome",
40-
"firefox",
41-
"iexplorer",
42-
"edge",
43-
"opera"
44-
])
71+
"chrome", "firefox", "iexplorer", "edge"])
4572
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
4673
def test_bot_modes_and_names(self, driver_mode, browser_name):
4774
"""Testcase: test_001_bot_local_chrome"""
@@ -57,12 +84,6 @@ def test_bot_modes_and_names(self, driver_mode, browser_name):
5784
pytest.skip(msg="Browser not configured")
5885
if browser_name == 'iexplorer':
5986
browser_name = 'internet explorer'
60-
if browser_name == 'opera':
61-
pytest.skip(
62-
msg=("Issue opened on official opera"
63-
" chromium github: "
64-
"https://github.com/operasoftware"
65-
"/operachromiumdriver/issues/9"))
6687
self.bot = BotBase(**settings)
6788
self.timer(wait=WAIT_TO_CLOSE)
6889
self.assert_is_instance(self.bot, BotBase)
@@ -72,9 +93,7 @@ def test_bot_modes_and_names(self, driver_mode, browser_name):
7293
self.assert_equals(self.bot.settings.get('mode'), driver_mode)
7394
self.assert_equals(self.bot.curr_caps['browserName'], browser_name)
7495

75-
@pytest.mark.parametrize("browser_name", [
76-
"chrome", "firefox", "opera"
77-
])
96+
@pytest.mark.parametrize("browser_name", ["chrome", "firefox"])
7897
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
7998
def test_bot_modes_headless(self, driver_mode, browser_name):
8099
"""Testcase: test_bot_modes_headless"""
@@ -86,12 +105,6 @@ def test_bot_modes_headless(self, driver_mode, browser_name):
86105
'mode': str(driver_mode),
87106
'options': {"headless": True}
88107
})
89-
if browser_name == 'opera':
90-
pytest.skip(
91-
msg=("Issue opened on official opera"
92-
" chromium github: "
93-
"https://github.com/operasoftware"
94-
"/operachromiumdriver/issues/9"))
95108
self.bot = BotBase(**settings)
96109
self.timer(wait=WAIT_TO_CLOSE)
97110
self.assert_is_instance(self.bot, BotBase)
@@ -101,20 +114,23 @@ def test_bot_modes_headless(self, driver_mode, browser_name):
101114
self.assert_equals(self.bot.settings.get('mode'), driver_mode)
102115
self.assert_equals(self.bot.curr_caps['browserName'], browser_name)
103116

117+
@pytest.mark.skipIf(SKIP, SKIP_MSG)
104118
def test_botbase_invalidsettingskey(self):
105119
"""Testcase: test_botbase_invalidsettingskey"""
106120
settings = SETTINGS.copy()
107121
settings.get('bot').update({"must_raises": "test"})
108122
with pytest.raises(CoreException):
109123
BotBase(**settings)
110124

125+
@pytest.mark.skipIf(SKIP, SKIP_MSG)
111126
def test_botbase_invalidmode(self):
112127
"""Testcase: test_botbase_invalidmode"""
113128
settings = SETTINGS.copy()
114129
settings.get('bot').update({"mode": "must_raises"})
115130
with pytest.raises(CoreException):
116131
self.bot = BotBase(**settings)
117132

133+
@pytest.mark.skipIf(SKIP, SKIP_MSG)
118134
def test_botbase_invalidbrowser(self):
119135
"""Testcase: test_botbase_invalidbrowser"""
120136
settings = SETTINGS.copy()

tests/002_benchmarks/suite_001_browsers.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ def bot_benchmark(self, browser_name, driver_mode, is_headless):
4747
pytest.skip(msg="Browser not configured")
4848
if browser_name == 'iexplorer':
4949
browser_name = 'internet explorer'
50-
if browser_name == 'opera':
51-
pytest.skip(
52-
msg=("Issue opened on official opera"
53-
" chromium github: "
54-
"https://github.com/operasoftware"
55-
"/operachromiumdriver/issues/9"))
5650
self.bot = BotBase(**settings)
5751
self.assert_is_instance(self.bot, BotBase)
5852
self.assert_equals(
@@ -69,12 +63,7 @@ def bot_benchmark(self, browser_name, driver_mode, is_headless):
6963

7064
@pytest.mark.benchmark(group='BROWSERS')
7165
@pytest.mark.parametrize("browser_name", [
72-
"chrome",
73-
"firefox",
74-
"iexplorer",
75-
"edge",
76-
"opera"
77-
])
66+
"chrome", "firefox", "iexplorer", "edge"])
7867
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
7968
@pytest.mark.skipIf(SKIP, SKIP_MSG)
8069
def test_benchmark_browsers(self, benchmark, browser_name, driver_mode):
@@ -93,9 +82,7 @@ def test_benchmark_browsers(self, benchmark, browser_name, driver_mode):
9382
rounds=ROUNDS)
9483

9584
@pytest.mark.benchmark(group='BROWSERS_HEADLESS')
96-
@pytest.mark.parametrize("browser_name", [
97-
"chrome", "firefox", "opera"
98-
])
85+
@pytest.mark.parametrize("browser_name", ["chrome", "firefox"])
9986
@pytest.mark.parametrize("driver_mode", ["local", "remote"])
10087
@pytest.mark.skipIf(SKIP, SKIP_MSG)
10188
def test_benchmark_browsers_headless(self, benchmark,

0 commit comments

Comments
 (0)