Skip to content
This repository was archived by the owner on Aug 10, 2022. It is now read-only.

Commit aa9008a

Browse files
authored
Merge pull request #22 from applitools/feature-add-get_all_test_results
Feature add get all test results
2 parents fe97961 + 266114a commit aa9008a

File tree

6 files changed

+116
-65
lines changed

6 files changed

+116
-65
lines changed

eyes_common/applitools/common/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .match_window_data import MatchWindowData, Options
3030
from .metadata import AppEnvironment, RunningSession, SessionStartInfo
3131
from .server import FailureReports, SessionType
32-
from .test_results import TestResults
32+
from .test_results import TestResults, TestResultSummary
3333
from .visual_grid import (
3434
ChromeEmulationInfo,
3535
DeviceName,

eyes_common/applitools/common/test_results.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
from .match import ImageMatchSettings
1010

1111
if typing.TYPE_CHECKING:
12-
from typing import Text, Any, Dict, Optional
12+
from typing import Text, Any, Dict, Optional, List
1313

1414
# TODO: Implement objects
1515
SessionUrls = Dict[Any, Any]
1616
StepInfo = Dict[Any, Any]
1717

18-
__all__ = ("TestResults",)
18+
__all__ = ("TestResults", "TestResultSummary")
1919

2020

2121
class TestResultsStatus(Enum):
@@ -98,3 +98,30 @@ def __str__(self):
9898
origin_str = super(TestResults, self).__str__()
9999
preamble = "New test" if self.is_new else "Existing test"
100100
return "{} [{}]".format(preamble, origin_str)
101+
102+
103+
@attr.s
104+
class TestResultSummary(object):
105+
all_results = attr.ib() # type: List[TestResults]
106+
exceptions = attr.ib(default=0)
107+
108+
passed = attr.ib(init=False, default=0)
109+
unresolved = attr.ib(init=False, default=0)
110+
failed = attr.ib(init=False, default=0)
111+
mismatches = attr.ib(init=False, default=0)
112+
missing = attr.ib(init=False, default=0)
113+
matches = attr.ib(init=False, default=0)
114+
115+
def __attrs_post_init__(self):
116+
for result in self.all_results:
117+
if result is None:
118+
continue
119+
if result.is_failed:
120+
self.failed += 1
121+
elif result.is_passed:
122+
self.passed += 1
123+
elif result.is_unresolved:
124+
self.unresolved += 1
125+
self.matches += result.matches
126+
self.missing += result.missing
127+
self.mismatches += result.mismatches

eyes_selenium/applitools/selenium/visual_grid/vg_task.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
import attr
55

6-
from applitools.common import logger
6+
from applitools.common import TestResults, logger
77

88
if typing.TYPE_CHECKING:
9-
from typing import Callable, Text
9+
from typing import Callable, Text, Optional
1010

1111

1212
@attr.s(hash=True)
@@ -35,7 +35,7 @@ def on_task_completed(self, code):
3535
return self
3636

3737
def __call__(self):
38-
# type: () -> None
38+
# type: () -> Optional[TestResults]
3939
logger.debug("%s called %s" % (self.__class__.__name__, self.name))
4040
res = None
4141
try:

eyes_selenium/applitools/selenium/visual_grid/visual_grid_eyes.py

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ class VisualGridEyes(object):
6969
_is_opened = False
7070
_driver = None
7171
rendering_info = None
72-
test_list = [] # type: List[RunningTest]
7372

7473
def __init__(self, runner, config):
7574
# type: (VisualGridRunner, Eyes)-> None
76-
self._elements = []
7775
self._config_provider = config
76+
self._elements = []
7877
argument_guard.not_none(runner)
7978
self.vg_manager = runner
79+
self.test_list = [] # type: List[RunningTest]
8080

8181
@property
8282
def is_opened(self):
@@ -185,56 +185,21 @@ def close_async(self):
185185
test.close()
186186

187187
def close(self, raise_ex=True): # noqa
188-
# type: (Optional[bool]) -> List[TestResults]
188+
# type: (Optional[bool]) -> Optional[TestResults]
189189
if self.configuration.is_disabled:
190190
logger.debug("close(): ignored (disabled)")
191-
return []
191+
return TestResults()
192192
if not self.test_list:
193-
return []
193+
return TestResults()
194194
logger.debug("VisualGridEyes.close()\n\t test_list %s" % self.test_list)
195195
self.close_async()
196-
197-
while True:
198-
completed_states = [
199-
test.state for test in self.test_list if test.state == "completed"
200-
]
201-
if len(completed_states) == len(self.test_list):
202-
break
203-
sleep(0.5)
196+
self.vg_manager.process_test_list(self.test_list, raise_ex)
204197
self._is_opened = False
205-
self.vg_manager.stop()
206-
logger.close()
207198

208-
for test in self.test_list:
209-
if test.pending_exceptions:
210-
raise EyesError(
211-
"During test execution above exception raised. \n {}".join(
212-
test.pending_exceptions
213-
)
214-
)
215-
216-
if raise_ex:
217-
for test in self.test_list:
218-
results = test.test_result
219-
msg = "Test '{}' of '{}'. \n\tSee details at: {}".format(
220-
results.name, results.app_name, results.url
221-
)
222-
if results.is_unresolved and not results.is_new:
223-
raise DiffsFoundError(msg, results)
224-
if results.is_new:
225-
raise NewTestError(msg, results)
226-
if results.is_failed:
227-
raise TestFailedError(msg, results)
228-
229-
failed_results = [
230-
test.test_result
231-
for test in self.test_list
232-
if test.test_result.is_unresolved or test.test_result.is_failed
233-
]
234-
return failed_results
235-
236-
def get_all_test_results(self):
237-
return [test.test_result for test in self.test_list]
199+
test_results = [t.test_result for t in self.test_list if t.test_result]
200+
if not test_results:
201+
return TestResults()
202+
return test_results[0]
238203

239204
def _create_vgeyes_connector(self, b_info):
240205
# type: (RenderBrowserInfo) -> EyesConnector

eyes_selenium/applitools/selenium/visual_grid/visual_grid_runner.py

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
import sys
21
import concurrent
32
import itertools
43
import operator
4+
import sys
55
import threading
66
import typing
77
from concurrent.futures import ThreadPoolExecutor
88
from time import sleep
99

10-
from applitools.common import logger
10+
from applitools.common import (
11+
DiffsFoundError,
12+
EyesError,
13+
NewTestError,
14+
TestFailedError,
15+
TestResultSummary,
16+
logger,
17+
)
1118
from applitools.selenium.visual_grid.resource_cache import ResourceCache
1219

1320
if typing.TYPE_CHECKING:
@@ -87,18 +94,49 @@ def stop(self):
8794
self.executor.shutdown()
8895
self.thread.join()
8996

90-
# def get_all_test_results(self):
91-
# # type: () -> List[TestResults]
92-
# while not any(e.is_opened for e in self.all_eyes):
93-
# sleep(0.5)
94-
# return list(
95-
# itertools.chain.from_iterable(
96-
# test.test_result
97-
# for e in self.all_eyes
98-
# for test in e.test_list
99-
# if e.test_list
100-
# )
101-
# )
97+
def process_test_list(self, test_list, raise_ex):
98+
while True:
99+
completed_states = [
100+
test.state for test in test_list if test.state == "completed"
101+
]
102+
if len(completed_states) == len(test_list):
103+
break
104+
sleep(0.5)
105+
self.stop()
106+
logger.close()
107+
108+
for test in test_list:
109+
if test.pending_exceptions:
110+
raise EyesError(
111+
"During test execution above exception raised. \n {}".join(
112+
test.pending_exceptions
113+
)
114+
)
115+
if raise_ex:
116+
for test in test_list:
117+
results = test.test_result
118+
msg = "Test '{}' of '{}'. \n\tSee details at: {}".format(
119+
results.name, results.app_name, results.url
120+
)
121+
if results.is_unresolved and not results.is_new:
122+
raise DiffsFoundError(msg, results)
123+
if results.is_new:
124+
raise NewTestError(msg, results)
125+
if results.is_failed:
126+
raise TestFailedError(msg, results)
127+
return test_list
128+
129+
def get_all_test_results(self, raise_ex=True):
130+
# type: (bool) -> TestResultSummary
131+
while not any(e.is_opened for e in self.all_eyes):
132+
sleep(0.5)
133+
test_list = self.process_test_list(
134+
[test for e in self.all_eyes for test in e.test_list], raise_ex
135+
)
136+
for e in self.all_eyes:
137+
e._is_opened = False
138+
exceptions = [exp for t in test_list for exp in t.pending_exceptions]
139+
return TestResultSummary([t.test_result for t in test_list], len(exceptions))
102140

103141
@property
104142
def all_running_tests(self):
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from applitools.selenium import BrowserType, Eyes
2+
3+
4+
def test_get_all_test_results(vg_runner, driver):
5+
eyes1 = Eyes(vg_runner)
6+
eyes2 = Eyes(vg_runner)
7+
eyes1.configuration.add_browser(800, 600, BrowserType.CHROME)
8+
eyes2.configuration.add_browser(700, 500, BrowserType.FIREFOX)
9+
10+
driver.get("https://demo.applitools.com")
11+
eyes1.open(driver, "Testing1", "TestClose1")
12+
eyes2.open(driver, "Testing2", "TestClose2")
13+
14+
eyes1.check_window()
15+
eyes2.check_window()
16+
17+
eyes1.close_async()
18+
eyes2.close_async()
19+
20+
results = vg_runner.get_all_test_results(False)
21+
print(results)

0 commit comments

Comments
 (0)