[Modern Media Controls] REGRESSION(r293684) cannot pause `<video>` if `controls`...
[WebKit-https.git] / WebDriverTests / imported / selenium / py / conftest.py
1 # Licensed to the Software Freedom Conservancy (SFC) under one
2 # or more contributor license agreements.  See the NOTICE file
3 # distributed with this work for additional information
4 # regarding copyright ownership.  The SFC licenses this file
5 # to you under the Apache License, Version 2.0 (the
6 # "License"); you may not use this file except in compliance
7 # with the License.  You may obtain a copy of the License at
8 #
9 #   http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing,
12 # software distributed under the License is distributed on an
13 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # KIND, either express or implied.  See the License for the
15 # specific language governing permissions and limitations
16 # under the License.
17
18 import os
19 import platform
20 import socket
21 import subprocess
22 import time
23
24 import pytest
25
26 from selenium import webdriver
27 from selenium.webdriver import DesiredCapabilities
28 from test.selenium.webdriver.common.webserver import SimpleWebServer
29 from test.selenium.webdriver.common.network import get_lan_ip
30
31 from urllib.request import urlopen
32
33 drivers = (
34     'Chrome',
35     'Edge',
36     'Firefox',
37     'Ie',
38     'Remote',
39     'Safari',
40     'WebKitGTK',
41     'ChromiumEdge',
42     'WPEWebKit',
43 )
44
45
46 def pytest_addoption(parser):
47     parser.addoption('--driver', action='append', choices=drivers, dest='drivers',
48                      metavar='DRIVER',
49                      help='driver to run tests against ({})'.format(', '.join(drivers)))
50     parser.addoption('--browser-binary', action='store', dest='binary',
51                      help='location of the browser binary')
52     parser.addoption('--driver-binary', action='store', dest='executable',
53                      help='location of the service executable binary')
54     parser.addoption('--browser-args', action='store', dest='args',
55                      help='arguments to start the browser with')
56
57
58 def pytest_ignore_collect(path, config):
59     drivers_opt = config.getoption('drivers')
60     _drivers = set(drivers).difference(drivers_opt or drivers)
61     if drivers_opt:
62         _drivers.add('unit')
63     parts = path.dirname.split(os.path.sep)
64     return len([d for d in _drivers if d.lower() in parts]) > 0
65
66
67 driver_instance = None
68
69
70 @pytest.fixture(scope='function')
71 def driver(request):
72     kwargs = {}
73
74     try:
75         driver_class = request.param
76     except AttributeError:
77         raise Exception('This test requires a --driver to be specified.')
78
79     # skip tests if not available on the platform
80     _platform = platform.system()
81     if driver_class == "Safari" and _platform != "Darwin":
82         pytest.skip("Safari tests can only run on an Apple OS")
83     if (driver_class == "Ie" or driver_class == "Edge") and _platform != "Windows":
84         pytest.skip("IE and EdgeHTML Tests can only run on Windows")
85     if "WebKit" in driver_class and _platform != "Linux":
86         pytest.skip("Webkit tests can only run on Linux")
87
88     # conditionally mark tests as expected to fail based on driver
89     marker = request.node.get_closest_marker('xfail_{0}'.format(driver_class.lower()))
90
91     if marker is not None:
92         if "run" in marker.kwargs:
93             if marker.kwargs["run"] is False:
94                 pytest.skip()
95                 yield
96                 return
97         if "raises" in marker.kwargs:
98             marker.kwargs.pop("raises")
99         pytest.xfail(**marker.kwargs)
100
101         def fin():
102             global driver_instance
103             if driver_instance is not None:
104                 driver_instance.quit()
105             driver_instance = None
106         request.addfinalizer(fin)
107
108     driver_path = request.config.option.executable
109     options = None
110
111     global driver_instance
112     if driver_instance is None:
113         if driver_class == 'Firefox':
114             options = get_options(driver_class, request.config)
115         if driver_class == 'Remote':
116             capabilities = DesiredCapabilities.FIREFOX.copy()
117             kwargs.update({'desired_capabilities': capabilities})
118             options = get_options('Firefox', request.config)
119         if driver_class == 'WebKitGTK':
120             options = get_options(driver_class, request.config)
121         if driver_class == 'ChromiumEdge':
122             options = get_options(driver_class, request.config)
123         if driver_class == 'WPEWebKit':
124             options = get_options(driver_class, request.config)
125         if driver_path is not None:
126             kwargs['executable_path'] = driver_path
127         if options is not None:
128             kwargs['options'] = options
129         driver_instance = getattr(webdriver, driver_class)(**kwargs)
130     yield driver_instance
131
132     if request.node.get_closest_marker("no_driver_after_test"):
133         driver_instance = None
134
135
136 def get_options(driver_class, config):
137     browser_path = config.option.binary
138     browser_args = config.option.args
139     options = None
140
141     if driver_class == 'ChromiumEdge':
142         options = getattr(webdriver, 'EdgeOptions')()
143         options.use_chromium = True
144
145     if browser_path or browser_args:
146         if not options:
147             options = getattr(webdriver, '{}Options'.format(driver_class))()
148         if driver_class == 'WebKitGTK':
149             options.overlay_scrollbars_enabled = False
150         if browser_path is not None:
151             options.binary_location = browser_path
152         if browser_args is not None:
153             for arg in browser_args.split():
154                 options.add_argument(arg)
155     return options
156
157
158 @pytest.fixture(scope='session', autouse=True)
159 def stop_driver(request):
160     def fin():
161         global driver_instance
162         if driver_instance is not None:
163             driver_instance.quit()
164         driver_instance = None
165     request.addfinalizer(fin)
166
167
168 def pytest_exception_interact(node, call, report):
169     if report.failed:
170         global driver_instance
171         if driver_instance is not None:
172             driver_instance.quit()
173         driver_instance = None
174
175
176 @pytest.fixture
177 def pages(driver, webserver):
178     class Pages(object):
179         def url(self, name):
180             return webserver.where_is(name)
181
182         def load(self, name):
183             driver.get(self.url(name))
184     return Pages()
185
186
187 @pytest.fixture(autouse=True, scope='session')
188 def server(request):
189     drivers = request.config.getoption('drivers')
190     if drivers is None or 'Remote' not in drivers:
191         yield None
192         return
193
194     _host = 'localhost'
195     _port = 4444
196     _path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
197                          'java/server/src/org/openqa/selenium/grid/selenium_server_deploy.jar')
198
199     def wait_for_server(url, timeout):
200         start = time.time()
201         while time.time() - start < timeout:
202             try:
203                 urlopen(url)
204                 return 1
205             except IOError:
206                 time.sleep(0.2)
207         return 0
208
209     _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
210     url = 'http://{}:{}/status'.format(_host, _port)
211     try:
212         _socket.connect((_host, _port))
213         print('The remote driver server is already running or something else'
214               'is using port {}, continuing...'.format(_port))
215     except Exception:
216         print('Starting the Selenium server')
217         process = subprocess.Popen(['java', '-jar', _path, 'standalone', '--port', '4444'])
218         print('Selenium server running as process: {}'.format(process.pid))
219         assert wait_for_server(url, 10), 'Timed out waiting for Selenium server at {}'.format(url)
220         print('Selenium server is ready')
221         yield process
222         process.terminate()
223         process.wait()
224         print('Selenium server has been terminated')
225
226
227 @pytest.fixture(autouse=True, scope='session')
228 def webserver():
229     webserver = SimpleWebServer(host=get_lan_ip())
230     webserver.start()
231     yield webserver
232     webserver.stop()