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

Commit c961dec

Browse files
authored
Merge pull request #11 from applitools/add-pre-hook
Add pre commit hook and black forrmatter
2 parents 771a27b + aca0251 commit c961dec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1984
-1111
lines changed

.bumpversion.cfg

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ tag = True
88
[bumpversion:file:eyes_images/applitools/images/__version__.py]
99

1010
[bumpversion:file:eyes_selenium/applitools/eyes_selenium/__version__.py]
11-

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ charset = utf-8
1414
[*.{py,rst,ini}]
1515
indent_style = space
1616
indent_size = 4
17-
max_line_length = 99
17+
max_line_length = 88
1818

1919
[*.rst]
2020
max_line_length = off

.pre-commit-config.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
repos:
2+
- repo: https://github.com/ambv/black
3+
rev: 18.9b0
4+
hooks:
5+
- id: black
6+
language_version: python3.7
7+
# override until resolved: https://github.com/ambv/black/issues/402
8+
files: \.pyi?$
9+
types: []
10+
11+
- repo: https://gitlab.com/pycqa/flake8
12+
rev: '3.7.3'
13+
hooks:
14+
- id: flake8
15+
language_version: python3.7
16+
17+
- repo: https://github.com/asottile/seed-isort-config
18+
rev: v1.5.0
19+
hooks:
20+
- id: seed-isort-config
21+
22+
- repo: https://github.com/pre-commit/mirrors-isort
23+
rev: v4.3.4
24+
hooks:
25+
- id: isort
26+
language_version: python3.7
27+
28+
- repo: https://github.com/pre-commit/pre-commit-hooks
29+
rev: v2.1.0
30+
hooks:
31+
- id: trailing-whitespace
32+
- id: end-of-file-fixer
33+
- id: debug-statements

README.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
|Build Status|
1+
|Build Status| |Black Formatter|
22

33
Eyes.Sdk.Python
44
===============
@@ -23,6 +23,8 @@ Please check the applitools website for usage instructions:
2323
- Python Image SDK example:
2424
https://applitools.com/tutorials/screenshots-python.html
2525

26+
.. |Black Formatter| image:: https://img.shields.io/badge/code%20style-black-000000.svg
27+
:target: https://github.com/ambv/black
2628
.. |Build Status| image:: https://travis-ci.org/applitools/eyes.sdk.python.svg?branch=master
2729
:target: https://travis-ci.org/applitools/eyes.sdk.python
2830

@@ -32,7 +34,7 @@ Development
3234

3335
For smother development experience install Invoke for task run first
3436

35-
::
37+
::
3638

3739
pip install invoke
3840
inv install-requirements # install libs required for development
@@ -41,13 +43,25 @@ For smother development experience install Invoke for task run first
4143
inv dist -core # publish eyes_core to test.pypi.org
4244
inv dist -core -prod # publish eyes_core to pypi.org
4345

46+
Install pre-commit hook
47+
***********************
48+
We're using `pre-commit <https://github.com/pre-commit/pre-commit>`_ for check and format code before commit. For
49+
manage hooks you could use invoke:
50+
51+
::
52+
53+
# installing of git hooks
54+
inv install-precommit-hook
55+
# removing of git hooks
56+
inv remove-precommit-hook
57+
4458

4559
Testing
4660
-------
4761

4862
For local testing, for example, images sdk
4963

5064
::
51-
65+
5266
inv install-packages -core -images
5367
inv test-run -images

eyes_core/applitools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore
1+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore

eyes_core/applitools/core/__init__.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@
1212
from .match import * # noqa
1313
from .metadata import * # noqa
1414

15-
__all__ = (triggers.__all__ + # noqa
16-
test_results.__all__ + # noqa
17-
match_window_task.__all__ + # noqa
18-
logger.__all__ + # noqa
19-
errors.__all__ + # noqa
20-
scaling.__all__ + # noqa
21-
capture.__all__ + # noqa
22-
eyes_base.__all__ + # noqa
23-
geometry.__all__ + # noqa
24-
positioning.__all__ + # noqa
25-
match.__all__ + # noqa
26-
metadata.__all__ + # noqa
27-
('logger', 'AgentConnector'))
15+
__all__ = (
16+
triggers.__all__ # noqa
17+
+ test_results.__all__ # noqa
18+
+ match_window_task.__all__ # noqa
19+
+ logger.__all__ # noqa
20+
+ errors.__all__ # noqa
21+
+ scaling.__all__ # noqa
22+
+ capture.__all__ # noqa
23+
+ eyes_base.__all__ # noqa
24+
+ geometry.__all__ # noqa
25+
+ positioning.__all__ # noqa
26+
+ match.__all__ # noqa
27+
+ metadata.__all__ # noqa
28+
+ ("logger", "AgentConnector") # noqa
29+
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.15.4'
1+
__version__ = "3.15.4"

eyes_core/applitools/core/agent_connector.py

Lines changed: 76 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# httplib.HTTPConnection.debuglevel = 1
2121

2222
# Remove Unverified SSL warnings propagated by requests' internal urllib3 module
23-
if hasattr(urllib3, 'disable_warnings') and callable(urllib3.disable_warnings):
23+
if hasattr(urllib3, "disable_warnings") and callable(urllib3.disable_warnings):
2424
urllib3.disable_warnings()
2525

2626

@@ -34,8 +34,12 @@ class AgentConnector(object):
3434
"""
3535
Provides an API for communication with the Applitools server.
3636
"""
37+
3738
_TIMEOUT = 60 * 5 # Seconds
38-
_DEFAULT_HEADERS = {'Accept': 'application/json', 'Content-Type': 'application/json'}
39+
_DEFAULT_HEADERS = {
40+
"Accept": "application/json",
41+
"Content-Type": "application/json",
42+
}
3943

4044
def __init__(self, server_url):
4145
# type: (tp.Text) -> None
@@ -60,18 +64,22 @@ def server_url(self):
6064
def server_url(self, server_url):
6165
# type: (tp.Text) -> None
6266
self._server_url = server_url # type: ignore
63-
self._endpoint_uri = server_url.rstrip('/') + '/api/sessions/running' # type: ignore
67+
self._endpoint_uri = ( # type: ignore
68+
server_url.rstrip("/") + "/api/sessions/running"
69+
)
6470

6571
@staticmethod
6672
def _send_long_request(name, method, *args, **kwargs):
6773
# type: (tp.Text, tp.Callable, *tp.Any, **tp.Any) -> Response
6874
delay = 2 # type: Num # Seconds
69-
headers = kwargs['headers'].copy()
70-
headers['Eyes-Expect'] = '202-accepted'
75+
headers = kwargs["headers"].copy()
76+
headers["Eyes-Expect"] = "202-accepted"
7177
while True:
7278
# Sending the current time of the request (in RFC 1123 format)
73-
headers['Eyes-Date'] = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())
74-
kwargs['headers'] = headers
79+
headers["Eyes-Date"] = time.strftime(
80+
"%a, %d %b %Y %H:%M:%S GMT", time.gmtime()
81+
)
82+
kwargs["headers"] = headers
7583
response = method(*args, **kwargs)
7684
if response.status_code != 202:
7785
return response
@@ -90,12 +98,20 @@ def start_session(self, session_start_info):
9098
:return: Represents the current running session.
9199
"""
92100
data = '{"startInfo": %s}' % (general_utils.to_json(session_start_info))
93-
response = requests.post(self._endpoint_uri, data=data, verify=False, params=dict(apiKey=self.api_key),
94-
headers=AgentConnector._DEFAULT_HEADERS,
95-
timeout=AgentConnector._TIMEOUT)
101+
response = requests.post(
102+
self._endpoint_uri,
103+
data=data,
104+
verify=False,
105+
params=dict(apiKey=self.api_key),
106+
headers=AgentConnector._DEFAULT_HEADERS,
107+
timeout=AgentConnector._TIMEOUT,
108+
)
96109
parsed_response = _parse_response_with_json_data(response)
97-
return dict(session_id=parsed_response['id'], session_url=parsed_response['url'],
98-
is_new_session=(response.status_code == requests.codes.created))
110+
return dict(
111+
session_id=parsed_response["id"],
112+
session_url=parsed_response["url"],
113+
is_new_session=(response.status_code == requests.codes.created),
114+
)
99115

100116
def stop_session(self, running_session, is_aborted, save):
101117
# type: (RunningSession, bool, bool) -> TestResults
@@ -107,39 +123,59 @@ def stop_session(self, running_session, is_aborted, save):
107123
:param save: Whether the session should be automatically saved if it is not aborted.
108124
:return: Test results of the stopped session.
109125
"""
110-
logger.debug('Stop session called..')
111-
session_uri = "%s/%s" % (self._endpoint_uri, running_session['session_id'])
112-
params = {'aborted': is_aborted, 'updateBaseline': save, 'apiKey': self.api_key}
113-
response = AgentConnector._send_long_request("stop_session", requests.delete, session_uri,
114-
params=params, verify=False,
115-
headers=AgentConnector._DEFAULT_HEADERS,
116-
timeout=AgentConnector._TIMEOUT)
126+
logger.debug("Stop session called..")
127+
session_uri = "%s/%s" % (self._endpoint_uri, running_session["session_id"])
128+
params = {"aborted": is_aborted, "updateBaseline": save, "apiKey": self.api_key}
129+
response = AgentConnector._send_long_request(
130+
"stop_session",
131+
requests.delete,
132+
session_uri,
133+
params=params,
134+
verify=False,
135+
headers=AgentConnector._DEFAULT_HEADERS,
136+
timeout=AgentConnector._TIMEOUT,
137+
)
117138
pr = _parse_response_with_json_data(response)
118139
logger.debug("stop_session(): parsed response: {}".format(pr))
119-
return TestResults(pr['steps'], pr['matches'], pr['mismatches'], pr['missing'],
120-
pr['exactMatches'], pr['strictMatches'], pr['contentMatches'],
121-
pr['layoutMatches'], pr['noneMatches'], pr['status'])
140+
return TestResults(
141+
pr["steps"],
142+
pr["matches"],
143+
pr["mismatches"],
144+
pr["missing"],
145+
pr["exactMatches"],
146+
pr["strictMatches"],
147+
pr["contentMatches"],
148+
pr["layoutMatches"],
149+
pr["noneMatches"],
150+
pr["status"],
151+
)
122152

123153
def match_window(self, running_session, data):
124154
# type: (RunningSession, tp.Text) -> bool
125155
"""
126-
Matches the current window to the immediate expected window in the Eyes server. Notice that
127-
a window might be matched later at the end of the test, even if it was not immediately
128-
matched in this call.
156+
Matches the current window to the immediate expected window in the Eyes server.
157+
Notice that a window might be matched later at the end of the test, even if it
158+
was not immediately matched in this call.
129159
130160
:param running_session: The current session that is running.
131161
:param data: The data for the requests.post.
132162
:return: The parsed response.
133163
"""
134164
# logger.debug("Data length: %d, data: %s" % (len(data), repr(data)))
135-
session_uri = "%s/%s" % (self._endpoint_uri, running_session['session_id'])
165+
session_uri = "%s/%s" % (self._endpoint_uri, running_session["session_id"])
136166
# Using the default headers, but modifying the "content type" to binary
137167
headers = AgentConnector._DEFAULT_HEADERS.copy()
138-
headers['Content-Type'] = 'application/octet-stream'
139-
response = requests.post(session_uri, params=dict(apiKey=self.api_key), data=data, verify=False,
140-
headers=headers, timeout=AgentConnector._TIMEOUT)
168+
headers["Content-Type"] = "application/octet-stream"
169+
response = requests.post(
170+
session_uri,
171+
params=dict(apiKey=self.api_key),
172+
data=data,
173+
verify=False,
174+
headers=headers,
175+
timeout=AgentConnector._TIMEOUT,
176+
)
141177
parsed_response = _parse_response_with_json_data(response)
142-
return parsed_response['asExpected']
178+
return parsed_response["asExpected"]
143179

144180
def post_dom_snapshot(self, dom_json):
145181
# type: (tp.Text) -> tp.Optional[tp.Text]
@@ -148,14 +184,16 @@ def post_dom_snapshot(self, dom_json):
148184
Return an URL of uploaded resource which should be posted to AppOutput.
149185
"""
150186
headers = AgentConnector._DEFAULT_HEADERS.copy()
151-
headers['Content-Type'] = 'application/octet-stream'
152-
dom_bytes = gzip_compress(dom_json.encode('utf-8'))
153-
response = requests.post(url=urljoin(self._endpoint_uri, 'running/data'),
154-
data=dom_bytes,
155-
params=dict(apiKey=self.api_key),
156-
headers=headers,
157-
timeout=AgentConnector._TIMEOUT)
187+
headers["Content-Type"] = "application/octet-stream"
188+
dom_bytes = gzip_compress(dom_json.encode("utf-8"))
189+
response = requests.post(
190+
url=urljoin(self._endpoint_uri, "running/data"),
191+
data=dom_bytes,
192+
params=dict(apiKey=self.api_key),
193+
headers=headers,
194+
timeout=AgentConnector._TIMEOUT,
195+
)
158196
dom_url = None
159197
if response.ok:
160-
dom_url = response.headers['Location']
198+
dom_url = response.headers["Location"]
161199
return dom_url

eyes_core/applitools/core/capture.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
if tp.TYPE_CHECKING:
99
from PIL import Image
1010

11-
__all__ = ('EyesScreenshot',)
11+
__all__ = ("EyesScreenshot",)
1212

1313

1414
class EyesScreenshot(ABC):
@@ -93,12 +93,20 @@ def convert_region_location(self, region, from_, to):
9393
argument_guard.not_none(to)
9494

9595
updated_location = self.convert_location(region.location, from_, to)
96-
return Region(updated_location.x, updated_location.y, region.width, region.height)
96+
return Region(
97+
updated_location.x, updated_location.y, region.width, region.height
98+
)
9799

98100
@property
99101
def image_region(self):
100102
# type: () -> Region
101-
return Region(0, 0, self._image.width, self._image.height, CoordinatesType.SCREENSHOT_AS_IS)
103+
return Region(
104+
0,
105+
0,
106+
self._image.width,
107+
self._image.height,
108+
CoordinatesType.SCREENSHOT_AS_IS,
109+
)
102110

103111
@property
104112
def bytes(self):

eyes_core/applitools/core/errors.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
__all__ = ('EyesError', 'EyesIllegalArgument', 'OutOfBoundsError', 'TestFailedError', 'NewTestError',
2-
'DiffsFoundError', 'CoordinatesTypeConversionError')
1+
__all__ = (
2+
"EyesError",
3+
"EyesIllegalArgument",
4+
"OutOfBoundsError",
5+
"TestFailedError",
6+
"NewTestError",
7+
"DiffsFoundError",
8+
"CoordinatesTypeConversionError",
9+
)
310

411

512
class EyesError(Exception):
@@ -54,5 +61,5 @@ def __init__(self, message, test_results=None):
5461

5562
class CoordinatesTypeConversionError(EyesError):
5663
def __init__(self, from_, to, test_results=None):
57-
message = 'Cannot convert from {} to {}'.format(from_, to)
64+
message = "Cannot convert from {} to {}".format(from_, to)
5865
super(CoordinatesTypeConversionError, self).__init__(message, test_results)

0 commit comments

Comments
 (0)