Backed out 8 changesets (bug 1470646) for linting failure on a CLOSED TREE

Backed out changeset 9b8d9f803b25 (bug 1470646)
Backed out changeset 58e2010d2842 (bug 1470646)
Backed out changeset 2b19429d778f (bug 1470646)
Backed out changeset e543f592454a (bug 1470646)
Backed out changeset 22469044267d (bug 1470646)
Backed out changeset e5415b1e22f5 (bug 1470646)
Backed out changeset 13e47fa99a31 (bug 1470646)
Backed out changeset 42964d651f02 (bug 1470646)

--HG--
rename : testing/marionette/capabilities.js => testing/marionette/session.js
rename : testing/marionette/test/unit/test_capabilities.js => testing/marionette/test/unit/test_session.js
This commit is contained in:
Coroiu Cristina 2018-07-02 17:56:27 +03:00
Родитель 54208e7808
Коммит cc751350dc
27 изменённых файлов: 427 добавлений и 463 удалений

Просмотреть файл

@ -1,285 +1,285 @@
# This Source Code Form is subject to the terms of the Mozilla Public # This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
from firefox_puppeteer import PuppeteerMixin from firefox_puppeteer import PuppeteerMixin
from marionette_harness import MarionetteTestCase from marionette_harness import MarionetteTestCase
class SessionStoreTestCase(PuppeteerMixin, MarionetteTestCase): class SessionStoreTestCase(PuppeteerMixin, MarionetteTestCase):
def setUp(self, startup_page=1, include_private=True, no_auto_updates=True): def setUp(self, startup_page=1, include_private=True, no_auto_updates=True):
super(SessionStoreTestCase, self).setUp() super(SessionStoreTestCase, self).setUp()
# Each list element represents a window of tabs loaded at # Each list element represents a window of tabs loaded at
# some testing URL # some testing URL
self.test_windows = set([ self.test_windows = set([
# Window 1. Note the comma after the absolute_url call - # Window 1. Note the comma after the absolute_url call -
# this is Python's way of declaring a 1 item tuple. # this is Python's way of declaring a 1 item tuple.
(self.marionette.absolute_url('layout/mozilla.html'), ), (self.marionette.absolute_url('layout/mozilla.html'), ),
# Window 2 # Window 2
(self.marionette.absolute_url('layout/mozilla_organizations.html'), (self.marionette.absolute_url('layout/mozilla_organizations.html'),
self.marionette.absolute_url('layout/mozilla_community.html')), self.marionette.absolute_url('layout/mozilla_community.html')),
# Window 3 # Window 3
(self.marionette.absolute_url('layout/mozilla_governance.html'), (self.marionette.absolute_url('layout/mozilla_governance.html'),
self.marionette.absolute_url('layout/mozilla_grants.html')), self.marionette.absolute_url('layout/mozilla_grants.html')),
]) ])
self.private_windows = set([ self.private_windows = set([
(self.marionette.absolute_url('layout/mozilla_mission.html'), (self.marionette.absolute_url('layout/mozilla_mission.html'),
self.marionette.absolute_url('layout/mozilla_organizations.html')), self.marionette.absolute_url('layout/mozilla_organizations.html')),
(self.marionette.absolute_url('layout/mozilla_projects.html'), (self.marionette.absolute_url('layout/mozilla_projects.html'),
self.marionette.absolute_url('layout/mozilla_mission.html')), self.marionette.absolute_url('layout/mozilla_mission.html')),
]) ])
self.marionette.enforce_gecko_prefs({ self.marionette.enforce_gecko_prefs({
# Set browser restore previous session pref, # Set browser restore previous session pref,
# depending on what the test requires. # depending on what the test requires.
'browser.startup.page': startup_page, 'browser.startup.page': startup_page,
# Make the content load right away instead of waiting for # Make the content load right away instead of waiting for
# the user to click on the background tabs # the user to click on the background tabs
'browser.sessionstore.restore_on_demand': False, 'browser.sessionstore.restore_on_demand': False,
# Avoid race conditions by having the content process never # Avoid race conditions by having the content process never
# send us session updates unless the parent has explicitly asked # send us session updates unless the parent has explicitly asked
# for them via the TabStateFlusher. # for them via the TabStateFlusher.
'browser.sessionstore.debug.no_auto_updates': no_auto_updates, 'browser.sessionstore.debug.no_auto_updates': no_auto_updates,
}) })
self.all_windows = self.test_windows.copy() self.all_windows = self.test_windows.copy()
self.open_windows(self.test_windows) self.open_windows(self.test_windows)
if include_private: if include_private:
self.all_windows.update(self.private_windows) self.all_windows.update(self.private_windows)
self.open_windows(self.private_windows, is_private=True) self.open_windows(self.private_windows, is_private=True)
def tearDown(self): def tearDown(self):
try: try:
# Create a fresh profile for subsequent tests. # Create a fresh profile for subsequent tests.
self.restart(clean=True) self.restart(clean=True)
finally: finally:
super(SessionStoreTestCase, self).tearDown() super(SessionStoreTestCase, self).tearDown()
def open_windows(self, window_sets, is_private=False): def open_windows(self, window_sets, is_private=False):
""" Opens a set of windows with tabs pointing at some """ Opens a set of windows with tabs pointing at some
URLs. URLs.
@param window_sets (list) @param window_sets (list)
A set of URL tuples. Each tuple within window_sets A set of URL tuples. Each tuple within window_sets
represents a window, and each URL in the URL represents a window, and each URL in the URL
tuples represents what will be loaded in a tab. tuples represents what will be loaded in a tab.
Note that if is_private is False, then the first Note that if is_private is False, then the first
URL tuple will be opened in the current window, and URL tuple will be opened in the current window, and
subequent tuples will be opened in new windows. subequent tuples will be opened in new windows.
Example: Example:
set( set(
(self.marionette.absolute_url('layout/mozilla_1.html'), (self.marionette.absolute_url('layout/mozilla_1.html'),
self.marionette.absolute_url('layout/mozilla_2.html')), self.marionette.absolute_url('layout/mozilla_2.html')),
(self.marionette.absolute_url('layout/mozilla_3.html'), (self.marionette.absolute_url('layout/mozilla_3.html'),
self.marionette.absolute_url('layout/mozilla_4.html')), self.marionette.absolute_url('layout/mozilla_4.html')),
) )
This would take the currently open window, and load This would take the currently open window, and load
mozilla_1.html and mozilla_2.html in new tabs. It would mozilla_1.html and mozilla_2.html in new tabs. It would
then open a new, second window, and load tabs at then open a new, second window, and load tabs at
mozilla_3.html and mozilla_4.html. mozilla_3.html and mozilla_4.html.
@param is_private (boolean, optional) @param is_private (boolean, optional)
Whether or not any new windows should be a private browsing Whether or not any new windows should be a private browsing
windows. windows.
""" """
if (is_private): if (is_private):
win = self.browser.open_browser(is_private=True) win = self.browser.open_browser(is_private=True)
win.switch_to() win.switch_to()
else: else:
win = self.browser win = self.browser
for index, urls in enumerate(window_sets): for index, urls in enumerate(window_sets):
if index > 0: if index > 0:
win = self.browser.open_browser(is_private=is_private) win = self.browser.open_browser(is_private=is_private)
win.switch_to() win.switch_to()
self.open_tabs(win, urls) self.open_tabs(win, urls)
def open_tabs(self, win, urls): def open_tabs(self, win, urls):
""" Opens a set of URLs inside a window in new tabs. """ Opens a set of URLs inside a window in new tabs.
@param win (browser window) @param win (browser window)
The browser window to load the tabs in. The browser window to load the tabs in.
@param urls (tuple) @param urls (tuple)
A tuple of URLs to load in this window. The A tuple of URLs to load in this window. The
first URL will be loaded in the currently selected first URL will be loaded in the currently selected
browser tab. Subsequent URLs will be loaded in browser tab. Subsequent URLs will be loaded in
new tabs. new tabs.
""" """
# If there are any remaining URLs for this window, # If there are any remaining URLs for this window,
# open some new tabs and navigate to them. # open some new tabs and navigate to them.
with self.marionette.using_context('content'): with self.marionette.using_context('content'):
if isinstance(urls, str): if isinstance(urls, str):
self.marionette.navigate(urls) self.marionette.navigate(urls)
else: else:
for index, url in enumerate(urls): for index, url in enumerate(urls):
if index > 0: if index > 0:
with self.marionette.using_context('chrome'): with self.marionette.using_context('chrome'):
win.tabbar.open_tab() win.tabbar.open_tab()
self.marionette.navigate(url) self.marionette.navigate(url)
def convert_open_windows_to_set(self): def convert_open_windows_to_set(self):
windows = self.puppeteer.windows.all windows = self.puppeteer.windows.all
# There's no guarantee that Marionette will return us an # There's no guarantee that Marionette will return us an
# iterator for the opened windows that will match the # iterator for the opened windows that will match the
# order within our window list. Instead, we'll convert # order within our window list. Instead, we'll convert
# the list of URLs within each open window to a set of # the list of URLs within each open window to a set of
# tuples that will allow us to do a direct comparison # tuples that will allow us to do a direct comparison
# while allowing the windows to be in any order. # while allowing the windows to be in any order.
opened_windows = set() opened_windows = set()
for win in windows: for win in windows:
urls = tuple() urls = tuple()
for tab in win.tabbar.tabs: for tab in win.tabbar.tabs:
urls = urls + tuple([tab.location]) urls = urls + tuple([tab.location])
opened_windows.add(urls) opened_windows.add(urls)
return opened_windows return opened_windows
def simulate_os_shutdown(self): def simulate_os_shutdown(self):
""" Simulate an OS shutdown. """ Simulate an OS shutdown.
:raises: Exception: if not supported on the current platform :raises: Exception: if not supported on the current platform
:raises: WindowsError: if a Windows API call failed :raises: WindowsError: if a Windows API call failed
""" """
if self.marionette.session_capabilities['platformName'] != 'windows': if self.marionette.session_capabilities['platformName'] != 'windows_nt':
raise Exception('Unsupported platform for simulate_os_shutdown') raise Exception('Unsupported platform for simulate_os_shutdown')
self._shutdown_with_windows_restart_manager(self.marionette.process_id) self._shutdown_with_windows_restart_manager(self.marionette.process_id)
def _shutdown_with_windows_restart_manager(self, pid): def _shutdown_with_windows_restart_manager(self, pid):
""" Shut down a process using the Windows Restart Manager. """ Shut down a process using the Windows Restart Manager.
When Windows shuts down, it uses a protocol including the When Windows shuts down, it uses a protocol including the
WM_QUERYENDSESSION and WM_ENDSESSION messages to give WM_QUERYENDSESSION and WM_ENDSESSION messages to give
applications a chance to shut down safely. The best way to applications a chance to shut down safely. The best way to
simulate this is via the Restart Manager, which allows a process simulate this is via the Restart Manager, which allows a process
(such as an installer) to use the same mechanism to shut down (such as an installer) to use the same mechanism to shut down
any other processes which are using registered resources. any other processes which are using registered resources.
This function starts a Restart Manager session, registers the This function starts a Restart Manager session, registers the
process as a resource, and shuts down the process. process as a resource, and shuts down the process.
:param pid: The process id (int) of the process to shutdown :param pid: The process id (int) of the process to shutdown
:raises: WindowsError: if a Windows API call fails :raises: WindowsError: if a Windows API call fails
""" """
import ctypes import ctypes
from ctypes import Structure, POINTER, WINFUNCTYPE, windll, pointer, WinError from ctypes import Structure, POINTER, WINFUNCTYPE, windll, pointer, WinError
from ctypes.wintypes import HANDLE, DWORD, BOOL, WCHAR, UINT, ULONG, LPCWSTR from ctypes.wintypes import HANDLE, DWORD, BOOL, WCHAR, UINT, ULONG, LPCWSTR
# set up Windows SDK types # set up Windows SDK types
OpenProcess = windll.kernel32.OpenProcess OpenProcess = windll.kernel32.OpenProcess
OpenProcess.restype = HANDLE OpenProcess.restype = HANDLE
OpenProcess.argtypes = [DWORD, # dwDesiredAccess OpenProcess.argtypes = [DWORD, # dwDesiredAccess
BOOL, # bInheritHandle BOOL, # bInheritHandle
DWORD] # dwProcessId DWORD] # dwProcessId
PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_QUERY_INFORMATION = 0x0400
class FILETIME(Structure): class FILETIME(Structure):
_fields_ = [('dwLowDateTime', DWORD), _fields_ = [('dwLowDateTime', DWORD),
('dwHighDateTime', DWORD)] ('dwHighDateTime', DWORD)]
LPFILETIME = POINTER(FILETIME) LPFILETIME = POINTER(FILETIME)
GetProcessTimes = windll.kernel32.GetProcessTimes GetProcessTimes = windll.kernel32.GetProcessTimes
GetProcessTimes.restype = BOOL GetProcessTimes.restype = BOOL
GetProcessTimes.argtypes = [HANDLE, # hProcess GetProcessTimes.argtypes = [HANDLE, # hProcess
LPFILETIME, # lpCreationTime LPFILETIME, # lpCreationTime
LPFILETIME, # lpExitTime LPFILETIME, # lpExitTime
LPFILETIME, # lpKernelTime LPFILETIME, # lpKernelTime
LPFILETIME] # lpUserTime LPFILETIME] # lpUserTime
ERROR_SUCCESS = 0 ERROR_SUCCESS = 0
class RM_UNIQUE_PROCESS(Structure): class RM_UNIQUE_PROCESS(Structure):
_fields_ = [('dwProcessId', DWORD), _fields_ = [('dwProcessId', DWORD),
('ProcessStartTime', FILETIME)] ('ProcessStartTime', FILETIME)]
RmStartSession = windll.rstrtmgr.RmStartSession RmStartSession = windll.rstrtmgr.RmStartSession
RmStartSession.restype = DWORD RmStartSession.restype = DWORD
RmStartSession.argtypes = [POINTER(DWORD), # pSessionHandle RmStartSession.argtypes = [POINTER(DWORD), # pSessionHandle
DWORD, # dwSessionFlags DWORD, # dwSessionFlags
POINTER(WCHAR)] # strSessionKey POINTER(WCHAR)] # strSessionKey
class GUID(ctypes.Structure): class GUID(ctypes.Structure):
_fields_ = [('Data1', ctypes.c_ulong), _fields_ = [('Data1', ctypes.c_ulong),
('Data2', ctypes.c_ushort), ('Data2', ctypes.c_ushort),
('Data3', ctypes.c_ushort), ('Data3', ctypes.c_ushort),
('Data4', ctypes.c_ubyte * 8)] ('Data4', ctypes.c_ubyte * 8)]
CCH_RM_SESSION_KEY = ctypes.sizeof(GUID) * 2 CCH_RM_SESSION_KEY = ctypes.sizeof(GUID) * 2
RmRegisterResources = windll.rstrtmgr.RmRegisterResources RmRegisterResources = windll.rstrtmgr.RmRegisterResources
RmRegisterResources.restype = DWORD RmRegisterResources.restype = DWORD
RmRegisterResources.argtypes = [DWORD, # dwSessionHandle RmRegisterResources.argtypes = [DWORD, # dwSessionHandle
UINT, # nFiles UINT, # nFiles
POINTER(LPCWSTR), # rgsFilenames POINTER(LPCWSTR), # rgsFilenames
UINT, # nApplications UINT, # nApplications
POINTER(RM_UNIQUE_PROCESS), # rgApplications POINTER(RM_UNIQUE_PROCESS), # rgApplications
UINT, # nServices UINT, # nServices
POINTER(LPCWSTR)] # rgsServiceNames POINTER(LPCWSTR)] # rgsServiceNames
RM_WRITE_STATUS_CALLBACK = WINFUNCTYPE(None, UINT) RM_WRITE_STATUS_CALLBACK = WINFUNCTYPE(None, UINT)
RmShutdown = windll.rstrtmgr.RmShutdown RmShutdown = windll.rstrtmgr.RmShutdown
RmShutdown.restype = DWORD RmShutdown.restype = DWORD
RmShutdown.argtypes = [DWORD, # dwSessionHandle RmShutdown.argtypes = [DWORD, # dwSessionHandle
ULONG, # lActionFlags ULONG, # lActionFlags
RM_WRITE_STATUS_CALLBACK] # fnStatus RM_WRITE_STATUS_CALLBACK] # fnStatus
RmEndSession = windll.rstrtmgr.RmEndSession RmEndSession = windll.rstrtmgr.RmEndSession
RmEndSession.restype = DWORD RmEndSession.restype = DWORD
RmEndSession.argtypes = [DWORD] # dwSessionHandle RmEndSession.argtypes = [DWORD] # dwSessionHandle
# Get the info needed to uniquely identify the process # Get the info needed to uniquely identify the process
hProc = OpenProcess(PROCESS_QUERY_INFORMATION, False, pid) hProc = OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
if not hProc: if not hProc:
raise WinError() raise WinError()
creationTime = FILETIME() creationTime = FILETIME()
exitTime = FILETIME() exitTime = FILETIME()
kernelTime = FILETIME() kernelTime = FILETIME()
userTime = FILETIME() userTime = FILETIME()
if not GetProcessTimes(hProc, if not GetProcessTimes(hProc,
pointer(creationTime), pointer(creationTime),
pointer(exitTime), pointer(exitTime),
pointer(kernelTime), pointer(kernelTime),
pointer(userTime)): pointer(userTime)):
raise WinError() raise WinError()
# Start the Restart Manager Session # Start the Restart Manager Session
dwSessionHandle = DWORD() dwSessionHandle = DWORD()
sessionKeyType = WCHAR * (CCH_RM_SESSION_KEY + 1) sessionKeyType = WCHAR * (CCH_RM_SESSION_KEY + 1)
sessionKey = sessionKeyType() sessionKey = sessionKeyType()
if RmStartSession(pointer(dwSessionHandle), 0, sessionKey) != ERROR_SUCCESS: if RmStartSession(pointer(dwSessionHandle), 0, sessionKey) != ERROR_SUCCESS:
raise WinError() raise WinError()
try: try:
UProcs_count = 1 UProcs_count = 1
UProcsArrayType = RM_UNIQUE_PROCESS * UProcs_count UProcsArrayType = RM_UNIQUE_PROCESS * UProcs_count
UProcs = UProcsArrayType(RM_UNIQUE_PROCESS(pid, creationTime)) UProcs = UProcsArrayType(RM_UNIQUE_PROCESS(pid, creationTime))
# Register the process as a resource # Register the process as a resource
if RmRegisterResources(dwSessionHandle, if RmRegisterResources(dwSessionHandle,
0, None, 0, None,
UProcs_count, UProcs, UProcs_count, UProcs,
0, None) != ERROR_SUCCESS: 0, None) != ERROR_SUCCESS:
raise WinError() raise WinError()
# Shut down all processes using registered resources # Shut down all processes using registered resources
if RmShutdown(dwSessionHandle, 0, if RmShutdown(dwSessionHandle, 0,
ctypes.cast(None, RM_WRITE_STATUS_CALLBACK)) != ERROR_SUCCESS: ctypes.cast(None, RM_WRITE_STATUS_CALLBACK)) != ERROR_SUCCESS:
raise WinError() raise WinError()
finally: finally:
RmEndSession(dwSessionHandle) RmEndSession(dwSessionHandle)

Просмотреть файл

@ -69,7 +69,7 @@ class TestPageInfoWindow(PuppeteerMixin, MarionetteTestCase):
platformName = self.marionette.session_capabilities['platformName'] platformName = self.marionette.session_capabilities['platformName']
for trigger in open_strategies: for trigger in open_strategies:
if trigger == 'shortcut' and platformName == 'windows': if trigger == 'shortcut' and platformName == 'windows_nt':
# The shortcut for page info window does not exist on windows. # The shortcut for page info window does not exist on windows.
self.assertRaises(ValueError, self.browser.open_page_info_window, self.assertRaises(ValueError, self.browser.open_page_info_window,
trigger=trigger) trigger=trigger)
@ -93,7 +93,7 @@ class TestPageInfoWindow(PuppeteerMixin, MarionetteTestCase):
platformName = self.marionette.session_capabilities['platformName'] platformName = self.marionette.session_capabilities['platformName']
for trigger in close_strategies: for trigger in close_strategies:
# menu only works on OS X # menu only works on OS X
if trigger == 'menu' and platformName != 'mac': if trigger == 'menu' and platformName != 'darwin':
continue continue
page_info = self.browser.open_page_info_window() page_info = self.browser.open_page_info_window()

Просмотреть файл

@ -17,10 +17,6 @@ const {
Context, Context,
WindowState, WindowState,
} = ChromeUtils.import("chrome://marionette/content/browser.js", {}); } = ChromeUtils.import("chrome://marionette/content/browser.js", {});
const {
Capabilities,
Timeouts,
} = ChromeUtils.import("chrome://marionette/content/capabilities.js", {});
ChromeUtils.import("chrome://marionette/content/capture.js"); ChromeUtils.import("chrome://marionette/content/capture.js");
const { const {
CertificateOverrideManager, CertificateOverrideManager,
@ -55,6 +51,7 @@ ChromeUtils.import("chrome://marionette/content/modal.js");
const {MarionettePrefs} = ChromeUtils.import("chrome://marionette/content/prefs.js", {}); const {MarionettePrefs} = ChromeUtils.import("chrome://marionette/content/prefs.js", {});
ChromeUtils.import("chrome://marionette/content/proxy.js"); ChromeUtils.import("chrome://marionette/content/proxy.js");
ChromeUtils.import("chrome://marionette/content/reftest.js"); ChromeUtils.import("chrome://marionette/content/reftest.js");
ChromeUtils.import("chrome://marionette/content/session.js");
const { const {
PollPromise, PollPromise,
TimedPromise, TimedPromise,
@ -147,7 +144,7 @@ this.GeckoDriver = function(appId, server) {
this.sandboxes = new Sandboxes(() => this.getCurrentWindow()); this.sandboxes = new Sandboxes(() => this.getCurrentWindow());
this.legacyactions = new legacyaction.Chain(); this.legacyactions = new legacyaction.Chain();
this.capabilities = new Capabilities(); this.capabilities = new session.Capabilities();
this.mm = globalMessageManager; this.mm = globalMessageManager;
this.listener = proxy.toListener( this.listener = proxy.toListener(
@ -706,7 +703,7 @@ GeckoDriver.prototype.newSession = async function(cmd) {
this.sessionID = WebElement.generateUUID(); this.sessionID = WebElement.generateUUID();
try { try {
this.capabilities = Capabilities.fromJSON(cmd.parameters); this.capabilities = session.Capabilities.fromJSON(cmd.parameters);
if (!this.secureTLS) { if (!this.secureTLS) {
logger.warn("TLS certificate errors will be ignored for this session"); logger.warn("TLS certificate errors will be ignored for this session");
@ -1875,7 +1872,7 @@ GeckoDriver.prototype.getTimeouts = function() {
GeckoDriver.prototype.setTimeouts = function(cmd) { GeckoDriver.prototype.setTimeouts = function(cmd) {
// merge with existing timeouts // merge with existing timeouts
let merged = Object.assign(this.timeouts.toJSON(), cmd.parameters); let merged = Object.assign(this.timeouts.toJSON(), cmd.parameters);
this.timeouts = Timeouts.fromJSON(merged); this.timeouts = session.Timeouts.fromJSON(merged);
}; };
/** Single tap. */ /** Single tap. */
@ -2858,7 +2855,7 @@ GeckoDriver.prototype.deleteSession = function() {
CertificateOverrideManager.uninstall(); CertificateOverrideManager.uninstall();
this.sessionID = null; this.sessionID = null;
this.capabilities = new Capabilities(); this.capabilities = new session.Capabilities();
}; };
/** /**

Просмотреть файл

@ -12,14 +12,14 @@ XPCOMUtils.defineLazyGetter(this, "log", Log.get);
this.EXPORTED_SYMBOLS = ["pprint", "truncate"]; this.EXPORTED_SYMBOLS = ["pprint", "truncate"];
const ELEMENT_NODE = 1;
const MAX_STRING_LENGTH = 250; const MAX_STRING_LENGTH = 250;
/** /**
* Pretty-print values passed to template strings. * Pretty-print values passed to template strings.
* *
* Usage:: * Usage:
* *
* <pre><code>
* const {pprint} = Cu.import("chrome://marionette/content/error.js", {}); * const {pprint} = Cu.import("chrome://marionette/content/error.js", {});
* let bool = {value: true}; * let bool = {value: true};
* pprint`Expected boolean, got ${bool}`; * pprint`Expected boolean, got ${bool}`;
@ -31,12 +31,13 @@ const MAX_STRING_LENGTH = 250;
* *
* pprint`Current window: ${window}`; * pprint`Current window: ${window}`;
* => '[object Window https://www.mozilla.org/]' * => '[object Window https://www.mozilla.org/]'
* </code></pre>
*/ */
function pprint(ss, ...values) { function pprint(ss, ...values) {
function pretty(val) { function pretty(val) {
let proto = Object.prototype.toString.call(val); let proto = Object.prototype.toString.call(val);
if (typeof val == "object" && val !== null &&
"nodeType" in val && val.nodeType === ELEMENT_NODE) { if (val && val.nodeType === 1) {
return prettyElement(val); return prettyElement(val);
} else if (["[object Window]", "[object ChromeWindow]"].includes(proto)) { } else if (["[object Window]", "[object ChromeWindow]"].includes(proto)) {
return prettyWindowGlobal(val); return prettyWindowGlobal(val);

Просмотреть файл

@ -21,17 +21,8 @@ class TestCapabilities(MarionetteTestCase):
processID: Services.appinfo.processID, processID: Services.appinfo.processID,
} }
""") """)
self.os_name = self.marionette.execute_script(""" self.os_name = self.marionette.execute_script(
let name = Services.sysinfo.getProperty("name"); "return Services.sysinfo.getProperty('name')").lower()
switch (name) {
case "Windows_NT":
return "windows";
case "Darwin":
return "mac";
default:
return name.toLowerCase();
}
""")
self.os_version = self.marionette.execute_script( self.os_version = self.marionette.execute_script(
"return Services.sysinfo.getProperty('version')") "return Services.sysinfo.getProperty('version')")

Просмотреть файл

@ -21,7 +21,7 @@ class TestKeyActions(WindowManagerMixin, MarionetteTestCase):
def setUp(self): def setUp(self):
super(TestKeyActions, self).setUp() super(TestKeyActions, self).setUp()
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -22,7 +22,7 @@ class BaseLegacyMouseAction(MarionetteTestCase):
def setUp(self): def setUp(self):
super(BaseLegacyMouseAction, self).setUp() super(BaseLegacyMouseAction, self).setUp()
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -65,7 +65,7 @@ class BaseMouseAction(MarionetteTestCase):
def setUp(self): def setUp(self):
super(BaseMouseAction, self).setUp() super(BaseMouseAction, self).setUp()
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -50,7 +50,7 @@ class BaseNavigationTestCase(WindowManagerMixin, MarionetteTestCase):
self.test_page_remote = self.marionette.absolute_url("test.html") self.test_page_remote = self.marionette.absolute_url("test.html")
self.test_page_slow_resource = self.marionette.absolute_url("slow_resource.html") self.test_page_slow_resource = self.marionette.absolute_url("slow_resource.html")
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -15,7 +15,7 @@ class TestSwitchToWindowContent(WindowManagerMixin, MarionetteTestCase):
def setUp(self): def setUp(self):
super(TestSwitchToWindowContent, self).setUp() super(TestSwitchToWindowContent, self).setUp()
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -22,7 +22,7 @@ class TypingTestCase(MarionetteTestCase):
def setUp(self): def setUp(self):
super(TypingTestCase, self).setUp() super(TypingTestCase, self).setUp()
if self.marionette.session_capabilities["platformName"] == "mac": if self.marionette.session_capabilities["platformName"] == "darwin":
self.mod_key = Keys.META self.mod_key = Keys.META
else: else:
self.mod_key = Keys.CONTROL self.mod_key = Keys.CONTROL

Просмотреть файл

@ -31,7 +31,7 @@ class TestWindowMaximize(MarionetteTestCase):
width=self.original_size["width"], height=self.original_size["height"]) width=self.original_size["width"], height=self.original_size["height"])
def assert_window_maximized(self, actual, delta=None): def assert_window_maximized(self, actual, delta=None):
if self.marionette.session_capabilities["platformName"] == "windows": if self.marionette.session_capabilities["platformName"] == "windows_nt":
delta = 16 delta = 16
else: else:
delta = 22 delta = 22

Просмотреть файл

@ -186,13 +186,13 @@ class TestWindowRect(MarionetteTestCase):
# On macOS, windows can only be moved off the screen on the # On macOS, windows can only be moved off the screen on the
# horizontal axis. The system menu bar also blocks windows from # horizontal axis. The system menu bar also blocks windows from
# being moved to (0,0). # being moved to (0,0).
elif os == "mac": elif os == "darwin":
self.assertEqual(-8, new_position["x"]) self.assertEqual(-8, new_position["x"])
self.assertEqual(23, new_position["y"]) self.assertEqual(23, new_position["y"])
# It turns out that Windows is the only platform on which the # It turns out that Windows is the only platform on which the
# window can be reliably positioned off-screen. # window can be reliably positioned off-screen.
elif os == "windows": elif os == "windows_nt":
self.assertEqual(-8, new_position["x"]) self.assertEqual(-8, new_position["x"])
self.assertEqual(-8, new_position["y"]) self.assertEqual(-8, new_position["y"])

Просмотреть файл

@ -10,7 +10,6 @@ marionette.jar:
content/assert.js (assert.js) content/assert.js (assert.js)
content/atom.js (atom.js) content/atom.js (atom.js)
content/browser.js (browser.js) content/browser.js (browser.js)
content/capabilities.js (capabilities.js)
content/capture.js (capture.js) content/capture.js (capture.js)
content/cert.js (cert.js) content/cert.js (cert.js)
content/cookie.js (cookie.js) content/cookie.js (cookie.js)
@ -35,6 +34,7 @@ marionette.jar:
content/reftest.js (reftest.js) content/reftest.js (reftest.js)
content/reftest.xul (reftest.xul) content/reftest.xul (reftest.xul)
content/server.js (server.js) content/server.js (server.js)
content/session.js (session.js)
content/stream-utils.js (stream-utils.js) content/stream-utils.js (stream-utils.js)
content/sync.js (sync.js) content/sync.js (sync.js)
content/transport.js (transport.js) content/transport.js (transport.js)

Просмотреть файл

@ -17,10 +17,6 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("chrome://marionette/content/accessibility.js"); ChromeUtils.import("chrome://marionette/content/accessibility.js");
ChromeUtils.import("chrome://marionette/content/action.js"); ChromeUtils.import("chrome://marionette/content/action.js");
ChromeUtils.import("chrome://marionette/content/atom.js"); ChromeUtils.import("chrome://marionette/content/atom.js");
const {
Capabilities,
PageLoadStrategy,
} = ChromeUtils.import("chrome://marionette/content/capabilities.js", {});
ChromeUtils.import("chrome://marionette/content/capture.js"); ChromeUtils.import("chrome://marionette/content/capture.js");
const { const {
element, element,
@ -45,6 +41,7 @@ ChromeUtils.import("chrome://marionette/content/legacyaction.js");
const {Log} = ChromeUtils.import("chrome://marionette/content/log.js", {}); const {Log} = ChromeUtils.import("chrome://marionette/content/log.js", {});
ChromeUtils.import("chrome://marionette/content/navigate.js"); ChromeUtils.import("chrome://marionette/content/navigate.js");
ChromeUtils.import("chrome://marionette/content/proxy.js"); ChromeUtils.import("chrome://marionette/content/proxy.js");
ChromeUtils.import("chrome://marionette/content/session.js");
XPCOMUtils.defineLazyGetter(this, "logger", () => Log.getWithPrefix(outerWindowID)); XPCOMUtils.defineLazyGetter(this, "logger", () => Log.getWithPrefix(outerWindowID));
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]); XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
@ -73,7 +70,7 @@ const SUPPORTED_STRATEGIES = new Set([
Object.defineProperty(this, "capabilities", { Object.defineProperty(this, "capabilities", {
get() { get() {
let payload = sendSyncMessage("Marionette:WebDriver:GetCapabilities"); let payload = sendSyncMessage("Marionette:WebDriver:GetCapabilities");
return Capabilities.fromJSON(payload[0]); return session.Capabilities.fromJSON(payload[0]);
}, },
configurable: true, configurable: true,
}); });
@ -281,7 +278,8 @@ const loadListener = {
// is also treaded specifically here, because it gets temporary // is also treaded specifically here, because it gets temporary
// loaded for new content processes, and we only want to rely on // loaded for new content processes, and we only want to rely on
// complete loads for it. // complete loads for it.
} else if ((capabilities.get("pageLoadStrategy") === PageLoadStrategy.Eager && } else if ((capabilities.get("pageLoadStrategy") ===
session.PageLoadStrategy.Eager &&
documentURI != "about:blank") || documentURI != "about:blank") ||
/about:blocked\?/.exec(documentURI)) { /about:blocked\?/.exec(documentURI)) {
this.stop(); this.stop();
@ -399,7 +397,8 @@ const loadListener = {
// Only wait if the page load strategy is not `none` // Only wait if the page load strategy is not `none`
loadEventExpected = loadEventExpected && loadEventExpected = loadEventExpected &&
(capabilities.get("pageLoadStrategy") !== PageLoadStrategy.None); (capabilities.get("pageLoadStrategy") !==
session.PageLoadStrategy.None);
if (loadEventExpected) { if (loadEventExpected) {
let startTime = new Date().getTime(); let startTime = new Date().getTime();

Просмотреть файл

@ -8,14 +8,12 @@ import marionette_driver
class Keys(marionette_driver.keys.Keys): class Keys(marionette_driver.keys.Keys):
""" """Proxy to marionette's keys with an "accel" provided for convenience
Proxy to Marionette's keys with an "accel" provided for convenience testing across platforms."""
testing across platforms.
"""
def __init__(self, marionette): def __init__(self, marionette):
self.is_mac = marionette.session_capabilities["platformName"] == "mac" self.isDarwin = marionette.session_capabilities['platformName'] == 'darwin'
@property @property
def ACCEL(self): def ACCEL(self):
return self.META if self.is_mac else self.CONTROL return self.META if self.isDarwin else self.CONTROL

Просмотреть файл

@ -246,7 +246,7 @@ class BrowserWindow(BaseWindow):
elif trigger == 'menu': elif trigger == 'menu':
self.menubar.select_by_id('tools-menu', 'menu_pageInfo') self.menubar.select_by_id('tools-menu', 'menu_pageInfo')
elif trigger == 'shortcut': elif trigger == 'shortcut':
if win.marionette.session_capabilities['platformName'] == 'windows': if win.marionette.session_capabilities['platformName'] == 'windows_nt':
raise ValueError('Page info shortcut not available on Windows.') raise ValueError('Page info shortcut not available on Windows.')
win.send_shortcut(win.localize_entity('pageInfoCmd.commandkey'), win.send_shortcut(win.localize_entity('pageInfoCmd.commandkey'),
accel=True) accel=True)

Просмотреть файл

@ -394,7 +394,7 @@ class BaseWindow(BaseLib):
platform = self.marionette.session_capabilities['platformName'] platform = self.marionette.session_capabilities['platformName']
keymap = { keymap = {
'accel': Keys.META if platform == "mac" else Keys.CONTROL, 'accel': Keys.META if platform == 'darwin' else Keys.CONTROL,
'alt': Keys.ALT, 'alt': Keys.ALT,
'cmd': Keys.COMMAND, 'cmd': Keys.COMMAND,
'ctrl': Keys.CONTROL, 'ctrl': Keys.CONTROL,

Просмотреть файл

@ -18,12 +18,7 @@ const {
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]); XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
this.EXPORTED_SYMBOLS = [ this.EXPORTED_SYMBOLS = ["session"];
"Capabilities",
"PageLoadStrategy",
"Proxy",
"Timeouts",
];
// Enable testing this module, as Services.appinfo.* is not available // Enable testing this module, as Services.appinfo.* is not available
// in xpcshell tests. // in xpcshell tests.
@ -31,8 +26,15 @@ const appinfo = {name: "<missing>", version: "<missing>"};
try { appinfo.name = Services.appinfo.name.toLowerCase(); } catch (e) {} try { appinfo.name = Services.appinfo.name.toLowerCase(); } catch (e) {}
try { appinfo.version = Services.appinfo.version; } catch (e) {} try { appinfo.version = Services.appinfo.version; } catch (e) {}
/**
* State associated with a WebDriver session.
*
* @namespace
*/
this.session = {};
/** Representation of WebDriver session timeouts. */ /** Representation of WebDriver session timeouts. */
class Timeouts { session.Timeouts = class {
constructor() { constructor() {
// disabled // disabled
this.implicit = 0; this.implicit = 0;
@ -42,7 +44,7 @@ class Timeouts {
this.script = 30000; this.script = 30000;
} }
toString() { return "[object Timeouts]"; } toString() { return "[object session.Timeouts]"; }
/** Marshals timeout durations to a JSON Object. */ /** Marshals timeout durations to a JSON Object. */
toJSON() { toJSON() {
@ -56,7 +58,7 @@ class Timeouts {
static fromJSON(json) { static fromJSON(json) {
assert.object(json, assert.object(json,
pprint`Expected "timeouts" to be an object, got ${json}`); pprint`Expected "timeouts" to be an object, got ${json}`);
let t = new Timeouts(); let t = new session.Timeouts();
for (let [type, ms] of Object.entries(json)) { for (let [type, ms] of Object.entries(json)) {
switch (type) { switch (type) {
@ -82,14 +84,14 @@ class Timeouts {
return t; return t;
} }
} };
/** /**
* Enum of page loading strategies. * Enum of page loading strategies.
* *
* @enum * @enum
*/ */
const PageLoadStrategy = { session.PageLoadStrategy = {
/** No page load strategy. Navigation will return immediately. */ /** No page load strategy. Navigation will return immediately. */
None: "none", None: "none",
/** /**
@ -105,7 +107,7 @@ const PageLoadStrategy = {
}; };
/** Proxy configuration object representation. */ /** Proxy configuration object representation. */
class Proxy { session.Proxy = class {
/** @class */ /** @class */
constructor() { constructor() {
this.proxyType = null; this.proxyType = null;
@ -255,7 +257,7 @@ class Proxy {
return [hostname, port]; return [hostname, port];
} }
let p = new Proxy(); let p = new session.Proxy();
if (typeof json == "undefined" || json === null) { if (typeof json == "undefined" || json === null) {
return p; return p;
} }
@ -354,23 +356,23 @@ class Proxy {
}); });
} }
toString() { return "[object Proxy]"; } toString() { return "[object session.Proxy]"; }
} };
/** WebDriver session capabilities representation. */ /** WebDriver session capabilities representation. */
class Capabilities extends Map { session.Capabilities = class extends Map {
/** @class */ /** @class */
constructor() { constructor() {
super([ super([
// webdriver // webdriver
["browserName", appinfo.name], ["browserName", appinfo.name],
["browserVersion", appinfo.version], ["browserVersion", appinfo.version],
["platformName", getWebDriverPlatformName()], ["platformName", Services.sysinfo.getProperty("name").toLowerCase()],
["platformVersion", Services.sysinfo.getProperty("version")], ["platformVersion", Services.sysinfo.getProperty("version")],
["pageLoadStrategy", PageLoadStrategy.Normal], ["pageLoadStrategy", session.PageLoadStrategy.Normal],
["acceptInsecureCerts", false], ["acceptInsecureCerts", false],
["timeouts", new Timeouts()], ["timeouts", new session.Timeouts()],
["proxy", new Proxy()], ["proxy", new session.Proxy()],
// features // features
["rotatable", appinfo.name == "B2G"], ["rotatable", appinfo.name == "B2G"],
@ -392,16 +394,17 @@ class Capabilities extends Map {
* JSON-safe capability value. * JSON-safe capability value.
*/ */
set(key, value) { set(key, value) {
if (key === "timeouts" && !(value instanceof Timeouts)) { if (key === "timeouts" && !(value instanceof session.Timeouts)) {
throw new TypeError(); throw new TypeError();
} else if (key === "proxy" && !(value instanceof Proxy)) { } else if (key === "proxy" && !(value instanceof session.Proxy)) {
throw new TypeError(); throw new TypeError();
} }
return super.set(key, value); return super.set(key, value);
} }
toString() { return "[object Capabilities]"; } /** @return {string} */
toString() { return "[object session.Capabilities]"; }
/** /**
* JSON serialisation of capabilities object. * JSON serialisation of capabilities object.
@ -418,7 +421,7 @@ class Capabilities extends Map {
* @param {Object.<string, *>=} json * @param {Object.<string, *>=} json
* WebDriver capabilities. * WebDriver capabilities.
* *
* @return {Capabilities} * @return {session.Capabilities}
* Internal representation of WebDriver capabilities. * Internal representation of WebDriver capabilities.
*/ */
static fromJSON(json) { static fromJSON(json) {
@ -428,12 +431,12 @@ class Capabilities extends Map {
assert.object(json, assert.object(json,
pprint`Expected "capabilities" to be an object, got ${json}"`); pprint`Expected "capabilities" to be an object, got ${json}"`);
return Capabilities.match_(json); return session.Capabilities.match_(json);
} }
// Matches capabilities as described by WebDriver. // Matches capabilities as described by WebDriver.
static match_(json = {}) { static match_(json = {}) {
let matched = new Capabilities(); let matched = new session.Capabilities();
for (let [k, v] of Object.entries(json)) { for (let [k, v] of Object.entries(json)) {
switch (k) { switch (k) {
@ -445,12 +448,12 @@ class Capabilities extends Map {
case "pageLoadStrategy": case "pageLoadStrategy":
if (v === null) { if (v === null) {
matched.set("pageLoadStrategy", PageLoadStrategy.Normal); matched.set("pageLoadStrategy", session.PageLoadStrategy.Normal);
} else { } else {
assert.string(v, assert.string(v,
pprint`Expected ${k} to be a string, got ${v}`); pprint`Expected ${k} to be a string, got ${v}`);
if (Object.values(PageLoadStrategy).includes(v)) { if (Object.values(session.PageLoadStrategy).includes(v)) {
matched.set("pageLoadStrategy", v); matched.set("pageLoadStrategy", v);
} else { } else {
throw new InvalidArgumentError( throw new InvalidArgumentError(
@ -461,12 +464,12 @@ class Capabilities extends Map {
break; break;
case "proxy": case "proxy":
let proxy = Proxy.fromJSON(v); let proxy = session.Proxy.fromJSON(v);
matched.set("proxy", proxy); matched.set("proxy", proxy);
break; break;
case "timeouts": case "timeouts":
let timeouts = Timeouts.fromJSON(v); let timeouts = session.Timeouts.fromJSON(v);
matched.set("timeouts", timeouts); matched.set("timeouts", timeouts);
break; break;
@ -492,27 +495,7 @@ class Capabilities extends Map {
return matched; return matched;
} }
} };
this.Capabilities = Capabilities;
this.PageLoadStrategy = PageLoadStrategy;
this.Proxy = Proxy;
this.Timeouts = Timeouts;
function getWebDriverPlatformName() {
let name = Services.sysinfo.getProperty("name");
switch (name) {
case "Windows_NT":
return "windows";
case "Darwin":
return "mac";
default:
return name.toLowerCase();
}
}
// Specialisation of |JSON.stringify| that produces JSON-safe object // Specialisation of |JSON.stringify| that produces JSON-safe object
// literals, dropping empty objects and entries which values are undefined // literals, dropping empty objects and entries which values are undefined

Просмотреть файл

@ -8,15 +8,10 @@ ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm");
const {InvalidArgumentError} = ChromeUtils.import("chrome://marionette/content/error.js", {}); const {InvalidArgumentError} = ChromeUtils.import("chrome://marionette/content/error.js", {});
const { ChromeUtils.import("chrome://marionette/content/session.js");
Capabilities,
PageLoadStrategy,
Proxy,
Timeouts,
} = ChromeUtils.import("chrome://marionette/content/capabilities.js", {});
add_test(function test_Timeouts_ctor() { add_test(function test_Timeouts_ctor() {
let ts = new Timeouts(); let ts = new session.Timeouts();
equal(ts.implicit, 0); equal(ts.implicit, 0);
equal(ts.pageLoad, 300000); equal(ts.pageLoad, 300000);
equal(ts.script, 30000); equal(ts.script, 30000);
@ -25,13 +20,13 @@ add_test(function test_Timeouts_ctor() {
}); });
add_test(function test_Timeouts_toString() { add_test(function test_Timeouts_toString() {
equal(new Timeouts().toString(), "[object Timeouts]"); equal(new session.Timeouts().toString(), "[object session.Timeouts]");
run_next_test(); run_next_test();
}); });
add_test(function test_Timeouts_toJSON() { add_test(function test_Timeouts_toJSON() {
let ts = new Timeouts(); let ts = new session.Timeouts();
deepEqual(ts.toJSON(), {"implicit": 0, "pageLoad": 300000, "script": 30000}); deepEqual(ts.toJSON(), {"implicit": 0, "pageLoad": 300000, "script": 30000});
run_next_test(); run_next_test();
@ -43,7 +38,7 @@ add_test(function test_Timeouts_fromJSON() {
pageLoad: 20, pageLoad: 20,
script: 30, script: 30,
}; };
let ts = Timeouts.fromJSON(json); let ts = session.Timeouts.fromJSON(json);
equal(ts.implicit, json.implicit); equal(ts.implicit, json.implicit);
equal(ts.pageLoad, json.pageLoad); equal(ts.pageLoad, json.pageLoad);
equal(ts.script, json.script); equal(ts.script, json.script);
@ -57,7 +52,7 @@ add_test(function test_Timeouts_fromJSON_unrecognised_field() {
script: 42, script: 42,
}; };
try { try {
Timeouts.fromJSON(json); session.Timeouts.fromJSON(json);
} catch (e) { } catch (e) {
equal(e.name, InvalidArgumentError.name); equal(e.name, InvalidArgumentError.name);
equal(e.message, "Unrecognised timeout: sessionId"); equal(e.message, "Unrecognised timeout: sessionId");
@ -68,7 +63,7 @@ add_test(function test_Timeouts_fromJSON_unrecognised_field() {
add_test(function test_Timeouts_fromJSON_invalid_type() { add_test(function test_Timeouts_fromJSON_invalid_type() {
try { try {
Timeouts.fromJSON({script: "foobar"}); session.Timeouts.fromJSON({script: "foobar"});
} catch (e) { } catch (e) {
equal(e.name, InvalidArgumentError.name); equal(e.name, InvalidArgumentError.name);
equal(e.message, "Expected [object String] \"script\" to be a positive integer, got [object String] \"foobar\""); equal(e.message, "Expected [object String] \"script\" to be a positive integer, got [object String] \"foobar\"");
@ -79,7 +74,7 @@ add_test(function test_Timeouts_fromJSON_invalid_type() {
add_test(function test_Timeouts_fromJSON_bounds() { add_test(function test_Timeouts_fromJSON_bounds() {
try { try {
Timeouts.fromJSON({script: -42}); session.Timeouts.fromJSON({script: -42});
} catch (e) { } catch (e) {
equal(e.name, InvalidArgumentError.name); equal(e.name, InvalidArgumentError.name);
equal(e.message, "Expected [object String] \"script\" to be a positive integer, got [object Number] -42"); equal(e.message, "Expected [object String] \"script\" to be a positive integer, got [object Number] -42");
@ -89,15 +84,15 @@ add_test(function test_Timeouts_fromJSON_bounds() {
}); });
add_test(function test_PageLoadStrategy() { add_test(function test_PageLoadStrategy() {
equal(PageLoadStrategy.None, "none"); equal(session.PageLoadStrategy.None, "none");
equal(PageLoadStrategy.Eager, "eager"); equal(session.PageLoadStrategy.Eager, "eager");
equal(PageLoadStrategy.Normal, "normal"); equal(session.PageLoadStrategy.Normal, "normal");
run_next_test(); run_next_test();
}); });
add_test(function test_Proxy_ctor() { add_test(function test_Proxy_ctor() {
let p = new Proxy(); let p = new session.Proxy();
let props = [ let props = [
"proxyType", "proxyType",
"httpProxy", "httpProxy",
@ -116,7 +111,7 @@ add_test(function test_Proxy_ctor() {
}); });
add_test(function test_Proxy_init() { add_test(function test_Proxy_init() {
let p = new Proxy(); let p = new session.Proxy();
// no changed made, and 5 (system) is default // no changed made, and 5 (system) is default
equal(p.init(), false); equal(p.init(), false);
@ -132,26 +127,26 @@ add_test(function test_Proxy_init() {
"http://localhost:1234"); "http://localhost:1234");
// direct // direct
p = new Proxy(); p = new session.Proxy();
p.proxyType = "direct"; p.proxyType = "direct";
ok(p.init()); ok(p.init());
equal(Preferences.get("network.proxy.type"), 0); equal(Preferences.get("network.proxy.type"), 0);
// autodetect // autodetect
p = new Proxy(); p = new session.Proxy();
p.proxyType = "autodetect"; p.proxyType = "autodetect";
ok(p.init()); ok(p.init());
equal(Preferences.get("network.proxy.type"), 4); equal(Preferences.get("network.proxy.type"), 4);
// system // system
p = new Proxy(); p = new session.Proxy();
p.proxyType = "system"; p.proxyType = "system";
ok(p.init()); ok(p.init());
equal(Preferences.get("network.proxy.type"), 5); equal(Preferences.get("network.proxy.type"), 5);
// manual // manual
for (let proxy of ["ftp", "http", "ssl", "socks"]) { for (let proxy of ["ftp", "http", "ssl", "socks"]) {
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
p.noProxy = ["foo", "bar"]; p.noProxy = ["foo", "bar"];
p[`${proxy}Proxy`] = "foo"; p[`${proxy}Proxy`] = "foo";
@ -171,7 +166,7 @@ add_test(function test_Proxy_init() {
} }
// empty no proxy should reset default exclustions // empty no proxy should reset default exclustions
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
p.noProxy = []; p.noProxy = [];
ok(p.init()); ok(p.init());
@ -181,30 +176,30 @@ add_test(function test_Proxy_init() {
}); });
add_test(function test_Proxy_toString() { add_test(function test_Proxy_toString() {
equal(new Proxy().toString(), "[object Proxy]"); equal(new session.Proxy().toString(), "[object session.Proxy]");
run_next_test(); run_next_test();
}); });
add_test(function test_Proxy_toJSON() { add_test(function test_Proxy_toJSON() {
let p = new Proxy(); let p = new session.Proxy();
deepEqual(p.toJSON(), {}); deepEqual(p.toJSON(), {});
// autoconfig url // autoconfig url
p = new Proxy(); p = new session.Proxy();
p.proxyType = "pac"; p.proxyType = "pac";
p.proxyAutoconfigUrl = "foo"; p.proxyAutoconfigUrl = "foo";
deepEqual(p.toJSON(), {proxyType: "pac", proxyAutoconfigUrl: "foo"}); deepEqual(p.toJSON(), {proxyType: "pac", proxyAutoconfigUrl: "foo"});
// manual proxy // manual proxy
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
deepEqual(p.toJSON(), {proxyType: "manual"}); deepEqual(p.toJSON(), {proxyType: "manual"});
for (let proxy of ["ftpProxy", "httpProxy", "sslProxy", "socksProxy"]) { for (let proxy of ["ftpProxy", "httpProxy", "sslProxy", "socksProxy"]) {
let expected = {proxyType: "manual"}; let expected = {proxyType: "manual"};
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
if (proxy == "socksProxy") { if (proxy == "socksProxy") {
@ -236,7 +231,7 @@ add_test(function test_Proxy_toJSON() {
} }
// noProxy: add brackets for IPv6 address // noProxy: add brackets for IPv6 address
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
p.noProxy = ["2001:db8::1"]; p.noProxy = ["2001:db8::1"];
let expected = {proxyType: "manual", noProxy: "[2001:db8::1]"}; let expected = {proxyType: "manual", noProxy: "[2001:db8::1]"};
@ -246,35 +241,35 @@ add_test(function test_Proxy_toJSON() {
}); });
add_test(function test_Proxy_fromJSON() { add_test(function test_Proxy_fromJSON() {
let p = new Proxy(); let p = new session.Proxy();
deepEqual(p, Proxy.fromJSON(undefined)); deepEqual(p, session.Proxy.fromJSON(undefined));
deepEqual(p, Proxy.fromJSON(null)); deepEqual(p, session.Proxy.fromJSON(null));
for (let typ of [true, 42, "foo", []]) { for (let typ of [true, 42, "foo", []]) {
Assert.throws(() => Proxy.fromJSON(typ), /InvalidArgumentError/); Assert.throws(() => session.Proxy.fromJSON(typ), /InvalidArgumentError/);
} }
// must contain a valid proxyType // must contain a valid proxyType
Assert.throws(() => Proxy.fromJSON({}), /InvalidArgumentError/); Assert.throws(() => session.Proxy.fromJSON({}), /InvalidArgumentError/);
Assert.throws(() => Proxy.fromJSON({proxyType: "foo"}), Assert.throws(() => session.Proxy.fromJSON({proxyType: "foo"}),
/InvalidArgumentError/); /InvalidArgumentError/);
// autoconfig url // autoconfig url
for (let url of [true, 42, [], {}]) { for (let url of [true, 42, [], {}]) {
Assert.throws(() => Proxy.fromJSON( Assert.throws(() => session.Proxy.fromJSON(
{proxyType: "pac", proxyAutoconfigUrl: url}), /InvalidArgumentError/); {proxyType: "pac", proxyAutoconfigUrl: url}), /InvalidArgumentError/);
} }
p = new Proxy(); p = new session.Proxy();
p.proxyType = "pac"; p.proxyType = "pac";
p.proxyAutoconfigUrl = "foo"; p.proxyAutoconfigUrl = "foo";
deepEqual(p, deepEqual(p,
Proxy.fromJSON({proxyType: "pac", proxyAutoconfigUrl: "foo"})); session.Proxy.fromJSON({proxyType: "pac", proxyAutoconfigUrl: "foo"}));
// manual proxy // manual proxy
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
deepEqual(p, Proxy.fromJSON({proxyType: "manual"})); deepEqual(p, session.Proxy.fromJSON({proxyType: "manual"}));
for (let proxy of ["httpProxy", "sslProxy", "ftpProxy", "socksProxy"]) { for (let proxy of ["httpProxy", "sslProxy", "ftpProxy", "socksProxy"]) {
let manual = {proxyType: "manual"}; let manual = {proxyType: "manual"};
@ -284,11 +279,11 @@ add_test(function test_Proxy_fromJSON() {
"foo:-1", "foo:65536", "foo/test", "foo#42", "foo?foo=bar", "foo:-1", "foo:65536", "foo/test", "foo#42", "foo?foo=bar",
"2001:db8::1"]) { "2001:db8::1"]) {
manual[proxy] = host; manual[proxy] = host;
Assert.throws(() => Proxy.fromJSON(manual), Assert.throws(() => session.Proxy.fromJSON(manual),
/InvalidArgumentError/); /InvalidArgumentError/);
} }
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
if (proxy == "socksProxy") { if (proxy == "socksProxy") {
manual.socksVersion = 5; manual.socksVersion = 5;
@ -312,7 +307,7 @@ add_test(function test_Proxy_fromJSON() {
p[`${proxy}`] = host_map[host].hostname; p[`${proxy}`] = host_map[host].hostname;
p[`${proxy}Port`] = host_map[host].port; p[`${proxy}Port`] = host_map[host].port;
deepEqual(p, Proxy.fromJSON(manual)); deepEqual(p, session.Proxy.fromJSON(manual));
} }
// Without a port the default port of the scheme is used // Without a port the default port of the scheme is used
@ -330,53 +325,52 @@ add_test(function test_Proxy_fromJSON() {
p[`${proxy}Port`] = default_ports[proxy]; p[`${proxy}Port`] = default_ports[proxy];
} }
deepEqual(p, Proxy.fromJSON(manual)); deepEqual(p, session.Proxy.fromJSON(manual));
} }
} }
// missing required socks version // missing required socks version
Assert.throws(() => Proxy.fromJSON( Assert.throws(() => session.Proxy.fromJSON(
{proxyType: "manual", socksProxy: "foo:1234"}), {proxyType: "manual", socksProxy: "foo:1234"}),
/InvalidArgumentError/); /InvalidArgumentError/);
// noProxy: invalid settings // noProxy: invalid settings
for (let noProxy of [true, 42, {}, null, "foo", for (let noProxy of [true, 42, {}, null, "foo",
[true], [42], [{}], [null]]) { [true], [42], [{}], [null]]) {
Assert.throws(() => Proxy.fromJSON( Assert.throws(() => session.Proxy.fromJSON(
{proxyType: "manual", noProxy}), {proxyType: "manual", noProxy}),
/InvalidArgumentError/); /InvalidArgumentError/);
} }
// noProxy: valid settings // noProxy: valid settings
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
for (let noProxy of [[], ["foo"], ["foo", "bar"], ["127.0.0.1"]]) { for (let noProxy of [[], ["foo"], ["foo", "bar"], ["127.0.0.1"]]) {
let manual = {proxyType: "manual", "noProxy": noProxy}; let manual = {proxyType: "manual", "noProxy": noProxy};
p.noProxy = noProxy; p.noProxy = noProxy;
deepEqual(p, Proxy.fromJSON(manual)); deepEqual(p, session.Proxy.fromJSON(manual));
} }
// noProxy: IPv6 needs brackets removed // noProxy: IPv6 needs brackets removed
p = new Proxy(); p = new session.Proxy();
p.proxyType = "manual"; p.proxyType = "manual";
p.noProxy = ["2001:db8::1"]; p.noProxy = ["2001:db8::1"];
let manual = {proxyType: "manual", "noProxy": ["[2001:db8::1]"]}; let manual = {proxyType: "manual", "noProxy": ["[2001:db8::1]"]};
deepEqual(p, Proxy.fromJSON(manual)); deepEqual(p, session.Proxy.fromJSON(manual));
run_next_test(); run_next_test();
}); });
add_test(function test_Capabilities_ctor() { add_test(function test_Capabilities_ctor() {
let caps = new Capabilities(); let caps = new session.Capabilities();
ok(caps.has("browserName")); ok(caps.has("browserName"));
ok(caps.has("browserVersion")); ok(caps.has("browserVersion"));
ok(caps.has("platformName")); ok(caps.has("platformName"));
ok(["linux", "mac", "windows", "android"].includes(caps.get("platformName")));
ok(caps.has("platformVersion")); ok(caps.has("platformVersion"));
equal(PageLoadStrategy.Normal, caps.get("pageLoadStrategy")); equal(session.PageLoadStrategy.Normal, caps.get("pageLoadStrategy"));
equal(false, caps.get("acceptInsecureCerts")); equal(false, caps.get("acceptInsecureCerts"));
ok(caps.get("timeouts") instanceof Timeouts); ok(caps.get("timeouts") instanceof session.Timeouts);
ok(caps.get("proxy") instanceof Proxy); ok(caps.get("proxy") instanceof session.Proxy);
ok(caps.has("rotatable")); ok(caps.has("rotatable"));
@ -390,13 +384,13 @@ add_test(function test_Capabilities_ctor() {
}); });
add_test(function test_Capabilities_toString() { add_test(function test_Capabilities_toString() {
equal("[object Capabilities]", new Capabilities().toString()); equal("[object session.Capabilities]", new session.Capabilities().toString());
run_next_test(); run_next_test();
}); });
add_test(function test_Capabilities_toJSON() { add_test(function test_Capabilities_toJSON() {
let caps = new Capabilities(); let caps = new session.Capabilities();
let json = caps.toJSON(); let json = caps.toJSON();
equal(caps.get("browserName"), json.browserName); equal(caps.get("browserName"), json.browserName);
@ -421,7 +415,7 @@ add_test(function test_Capabilities_toJSON() {
}); });
add_test(function test_Capabilities_fromJSON() { add_test(function test_Capabilities_fromJSON() {
const {fromJSON} = Capabilities; const {fromJSON} = session.Capabilities;
// plain // plain
for (let typ of [{}, null, undefined]) { for (let typ of [{}, null, undefined]) {
@ -432,7 +426,7 @@ add_test(function test_Capabilities_fromJSON() {
} }
// matching // matching
let caps = new Capabilities(); let caps = new session.Capabilities();
caps = fromJSON({acceptInsecureCerts: true}); caps = fromJSON({acceptInsecureCerts: true});
equal(true, caps.get("acceptInsecureCerts")); equal(true, caps.get("acceptInsecureCerts"));
@ -440,7 +434,7 @@ add_test(function test_Capabilities_fromJSON() {
equal(false, caps.get("acceptInsecureCerts")); equal(false, caps.get("acceptInsecureCerts"));
Assert.throws(() => fromJSON({acceptInsecureCerts: "foo"}), InvalidArgumentError); Assert.throws(() => fromJSON({acceptInsecureCerts: "foo"}), InvalidArgumentError);
for (let strategy of Object.values(PageLoadStrategy)) { for (let strategy of Object.values(session.PageLoadStrategy)) {
caps = fromJSON({pageLoadStrategy: strategy}); caps = fromJSON({pageLoadStrategy: strategy});
equal(strategy, caps.get("pageLoadStrategy")); equal(strategy, caps.get("pageLoadStrategy"));
} }
@ -480,9 +474,9 @@ add_test(function test_Capabilities_fromJSON() {
run_next_test(); run_next_test();
}); });
// use Proxy.toJSON to test marshal // use session.Proxy.toJSON to test marshal
add_test(function test_marshal() { add_test(function test_marshal() {
let proxy = new Proxy(); let proxy = new session.Proxy();
// drop empty fields // drop empty fields
deepEqual({}, proxy.toJSON()); deepEqual({}, proxy.toJSON());
@ -498,7 +492,7 @@ add_test(function test_marshal() {
deepEqual({proxyType: {foo: "bar"}}, proxy.toJSON()); deepEqual({proxyType: {foo: "bar"}}, proxy.toJSON());
// iterate over complex object that implement toJSON // iterate over complex object that implement toJSON
proxy.proxyType = new Proxy(); proxy.proxyType = new session.Proxy();
deepEqual({}, proxy.toJSON()); deepEqual({}, proxy.toJSON());
proxy.proxyType.proxyType = "manual"; proxy.proxyType.proxyType = "manual";
deepEqual({proxyType: {proxyType: "manual"}}, proxy.toJSON()); deepEqual({proxyType: {proxyType: "manual"}}, proxy.toJSON());
@ -506,7 +500,7 @@ add_test(function test_marshal() {
// drop objects with no entries // drop objects with no entries
proxy.proxyType = {foo: {}}; proxy.proxyType = {foo: {}};
deepEqual({}, proxy.toJSON()); deepEqual({}, proxy.toJSON());
proxy.proxyType = {foo: new Proxy()}; proxy.proxyType = {foo: new session.Proxy()};
deepEqual({}, proxy.toJSON()); deepEqual({}, proxy.toJSON());
run_next_test(); run_next_test();

Просмотреть файл

@ -8,7 +8,6 @@ skip-if = appname == "thunderbird"
[test_action.js] [test_action.js]
[test_assert.js] [test_assert.js]
[test_browser.js] [test_browser.js]
[test_capabilities.js]
[test_cookie.js] [test_cookie.js]
[test_dom.js] [test_dom.js]
[test_element.js] [test_element.js]
@ -18,4 +17,5 @@ skip-if = appname == "thunderbird"
[test_message.js] [test_message.js]
[test_navigate.js] [test_navigate.js]
[test_prefs.js] [test_prefs.js]
[test_session.js]
[test_sync.js] [test_sync.js]

Просмотреть файл

@ -619878,7 +619878,7 @@
"support" "support"
], ],
"webdriver/tests/actions/control_click.py": [ "webdriver/tests/actions/control_click.py": [
"cbe7cc08b4a991da0cce1dfefd96b25be3b50138", "341a8fbfe64f5231a91999768de0b44bba121122",
"wdspec" "wdspec"
], ],
"webdriver/tests/actions/key.py": [ "webdriver/tests/actions/key.py": [
@ -619922,7 +619922,7 @@
"support" "support"
], ],
"webdriver/tests/actions/support/keys.py": [ "webdriver/tests/actions/support/keys.py": [
"b06f684335c4ebb18ee8d0dd9e9b757f4cdcd52a", "528ab8473914c14f9671d89b8a888d30162714ec",
"support" "support"
], ],
"webdriver/tests/actions/support/mouse.py": [ "webdriver/tests/actions/support/mouse.py": [
@ -620318,7 +620318,7 @@
"support" "support"
], ],
"webdriver/tests/new_session/create_alwaysMatch.py": [ "webdriver/tests/new_session/create_alwaysMatch.py": [
"d0100b96ccdcc99bccd7bd611bd9df2f51c4a728", "b2783003e5e1a7d762a4340b33f65d6afd9b0e62",
"wdspec" "wdspec"
], ],
"webdriver/tests/new_session/create_firstMatch.py": [ "webdriver/tests/new_session/create_firstMatch.py": [
@ -620386,7 +620386,7 @@
"support" "support"
], ],
"webdriver/tests/set_window_rect/set.py": [ "webdriver/tests/set_window_rect/set.py": [
"04161b59c5b144dd571dca3ef224595f9d4612f2", "79de443bc251f7effaa7c2ef3b95695f22db01c6",
"wdspec" "wdspec"
], ],
"webdriver/tests/set_window_rect/user_prompts.py": [ "webdriver/tests/set_window_rect/user_prompts.py": [

Просмотреть файл

@ -407,7 +407,7 @@ class WdspecTest(Test):
test_type = "wdspec" test_type = "wdspec"
default_timeout = 25 default_timeout = 25
long_timeout = 180 # 3 minutes long_timeout = 120
manifest_test_cls = {"reftest": ReftestTest, manifest_test_cls = {"reftest": ReftestTest,

Просмотреть файл

@ -18,7 +18,7 @@ def test_control_click(session, test_actions_page, key_chain, mouse_chain, modif
outer = session.find.css("#outer", all=False) outer = session.find.css("#outer", all=False)
mouse_chain.click(element=outer) mouse_chain.click(element=outer)
session.actions.perform([key_chain.dict, mouse_chain.dict]) session.actions.perform([key_chain.dict, mouse_chain.dict])
if os == "windows": if os == "windows_nt":
expected = [ expected = [
{"type": "mousemove"}, {"type": "mousemove"},
{"type": "mousedown"}, {"type": "mousedown"},

Просмотреть файл

@ -15,7 +15,9 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
"""The Keys implementation.""" """
The Keys implementation.
"""
from inspect import getmembers from inspect import getmembers
import sys import sys
@ -25,7 +27,7 @@ class Keys(object):
""" """
Set of special keys codes. Set of special keys codes.
See also https://w3c.github.io/webdriver/#h-keyboard-actions See also https://w3c.github.io/webdriver/webdriver-spec.html#h-keyboard-actions
""" """
NULL = u"\ue000" NULL = u"\ue000"
@ -740,7 +742,7 @@ ALL_EVENTS = {
} }
} }
if sys.platform == "mac": if sys.platform == 'darwin':
MODIFIER_KEY = Keys.META MODIFIER_KEY = Keys.META
else: else:
MODIFIER_KEY = Keys.CONTROL MODIFIER_KEY = Keys.CONTROL

Просмотреть файл

@ -13,4 +13,3 @@ def test_valid(new_session, add_browser_capabilites, key, value):
response, _ = new_session({"capabilities": { response, _ = new_session({"capabilities": {
"alwaysMatch": add_browser_capabilites({key: value})}}) "alwaysMatch": add_browser_capabilites({key: value})}})
assert_success(response) assert_success(response)

Просмотреть файл

@ -334,7 +334,7 @@ def test_negative_x_y(session):
# On macOS, windows can only be moved off the screen on the # On macOS, windows can only be moved off the screen on the
# horizontal axis. The system menu bar also blocks windows from # horizontal axis. The system menu bar also blocks windows from
# being moved to (0,0). # being moved to (0,0).
elif os == "mac": elif os == "darwin":
assert_success(response, {"x": -8, assert_success(response, {"x": -8,
"y": 23, "y": 23,
"width": original["width"], "width": original["width"],
@ -342,7 +342,7 @@ def test_negative_x_y(session):
# It turns out that Windows is the only platform on which the # It turns out that Windows is the only platform on which the
# window can be reliably positioned off-screen. # window can be reliably positioned off-screen.
elif os == "windows": elif os == "windows_nt":
assert_success(response, {"x": -8, assert_success(response, {"x": -8,
"y": -8, "y": -8,
"width": original["width"], "width": original["width"],