зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
This commit is contained in:
Коммит
ae855cdb28
|
@ -128,6 +128,7 @@ devtools/shared/*.js
|
|||
!devtools/shared/css-lexer.js
|
||||
!devtools/shared/defer.js
|
||||
!devtools/shared/event-emitter.js
|
||||
!devtools/shared/loader-plugin-raw.jsm
|
||||
!devtools/shared/task.js
|
||||
devtools/shared/*.jsm
|
||||
!devtools/shared/Loader.jsm
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<em:version>1.0</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
||||
<!-- Target Application this theme can install into,
|
||||
with minimum and maximum supported versions. -->
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<em:version>1.0</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
||||
<!-- Target Application this theme can install into,
|
||||
with minimum and maximum supported versions. -->
|
||||
|
|
|
@ -101,6 +101,12 @@ function BrowserLoaderBuilder({ baseURI, window, useOnlyShared }) {
|
|||
paths: Object.assign({}, dynamicPaths, loaderOptions.paths),
|
||||
invisibleToDebugger: loaderOptions.invisibleToDebugger,
|
||||
requireHook: (id, require) => {
|
||||
// If |id| requires special handling, simply defer to devtools
|
||||
// immediately.
|
||||
if (devtools.isLoaderPluginId(id)) {
|
||||
return devtools.require(id);
|
||||
}
|
||||
|
||||
const uri = require.resolve(id);
|
||||
let isBrowserDir = BROWSER_BASED_DIRS.filter(dir => {
|
||||
return uri.startsWith(dir);
|
||||
|
|
|
@ -147,6 +147,7 @@ skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
|
|||
[browser_poller.js]
|
||||
[browser_prefs-01.js]
|
||||
[browser_prefs-02.js]
|
||||
[browser_require_raw.js]
|
||||
[browser_spectrum.js]
|
||||
[browser_theme.js]
|
||||
[browser_tableWidget_basic.js]
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
|
||||
|
||||
const { require: browserRequire } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/shared/",
|
||||
window: this
|
||||
});
|
||||
|
||||
const variableFileContents = browserRequire("raw!devtools/client/themes/variables.css");
|
||||
|
||||
function test() {
|
||||
ok(variableFileContents.length > 0, "raw browserRequire worked");
|
||||
finish();
|
||||
}
|
|
@ -9,45 +9,21 @@
|
|||
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
|
||||
*/
|
||||
|
||||
const { Cu } = require("chrome");
|
||||
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
const Services = require("Services");
|
||||
const { gDevTools } = require("devtools/client/framework/devtools");
|
||||
|
||||
const VARIABLES_URI = "chrome://devtools/skin/variables.css";
|
||||
const variableFileContents = require("raw!devtools/client/themes/variables.css");
|
||||
|
||||
const THEME_SELECTOR_STRINGS = {
|
||||
light: ":root.theme-light {",
|
||||
dark: ":root.theme-dark {"
|
||||
};
|
||||
|
||||
let variableFileContents;
|
||||
|
||||
/**
|
||||
* Returns a string of the file found at URI
|
||||
*/
|
||||
function readURI(uri) {
|
||||
let stream = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(uri, "UTF-8"),
|
||||
loadUsingSystemPrincipal: true}
|
||||
).open2();
|
||||
|
||||
let count = stream.available();
|
||||
let data = NetUtil.readInputStreamToString(stream, count, {
|
||||
charset: "UTF-8"
|
||||
});
|
||||
stream.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a theme name and returns the contents of its variable rule block.
|
||||
* The first time this runs fetches the variables CSS file and caches it.
|
||||
*/
|
||||
function getThemeFile(name) {
|
||||
if (!variableFileContents) {
|
||||
variableFileContents = readURI(VARIABLES_URI);
|
||||
}
|
||||
|
||||
// If there's no theme expected for this name, use `light` as default.
|
||||
let selector = THEME_SELECTOR_STRINGS[name] ||
|
||||
THEME_SELECTOR_STRINGS.light;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
var { utils: Cu } = Components;
|
||||
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
var { Loader, descriptor, resolveURI } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
|
||||
var { requireRawId } = Cu.import("resource://devtools/shared/loader-plugin-raw.jsm", {});
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DevToolsLoader", "devtools", "BuiltinProvider",
|
||||
"require", "loader"];
|
||||
|
@ -59,6 +60,12 @@ BuiltinProvider.prototype = {
|
|||
invisibleToDebugger: this.invisibleToDebugger,
|
||||
sharedGlobal: true,
|
||||
sharedGlobalBlocklist,
|
||||
requireHook: (id, require) => {
|
||||
if (id.startsWith("raw!")) {
|
||||
return requireRawId(id, require);
|
||||
}
|
||||
return require(id);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -120,6 +127,14 @@ DevToolsLoader.prototype = {
|
|||
return this.require.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true if |id| refers to something requiring help from a
|
||||
* loader plugin.
|
||||
*/
|
||||
isLoaderPluginId: function (id) {
|
||||
return id.startsWith("raw!");
|
||||
},
|
||||
|
||||
/**
|
||||
* Override the provider used to load the tools.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { utils: Cu } = Components;
|
||||
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
|
||||
/**
|
||||
* A function that can be used as part of a require hook for a
|
||||
* loader.js Loader. This function only handles webpack-style "raw!"
|
||||
* requires; other requires should not be passed to this. See
|
||||
* https://github.com/webpack/raw-loader.
|
||||
*/
|
||||
function requireRawId(id, require) {
|
||||
let uri = require.resolve(id.slice(4));
|
||||
// If the original string did not end with ".js", then
|
||||
// require.resolve might have added the suffix. We don't want to
|
||||
// add a suffix for a raw load (if needed the caller can specify it
|
||||
// manually), so remove it here.
|
||||
if (!id.endsWith(".js") && uri.endsWith(".js")) {
|
||||
uri = uri.slice(0, -3);
|
||||
}
|
||||
let stream = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(uri, "UTF-8"),
|
||||
loadUsingSystemPrincipal: true
|
||||
}).open2();
|
||||
|
||||
let count = stream.available();
|
||||
let data = NetUtil.readInputStreamToString(stream, count, {
|
||||
charset: "UTF-8"
|
||||
});
|
||||
stream.close();
|
||||
|
||||
// For the time being it doesn't seem worthwhile to cache the
|
||||
// result here.
|
||||
return data;
|
||||
}
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["requireRawId"];
|
|
@ -54,6 +54,7 @@ DevToolsModules(
|
|||
'dom-node-filter-constants.js',
|
||||
'event-emitter.js',
|
||||
'indentation.js',
|
||||
'loader-plugin-raw.jsm',
|
||||
'Loader.jsm',
|
||||
'Parser.jsm',
|
||||
'path.js',
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test require using "raw!".
|
||||
|
||||
function run_test() {
|
||||
let loader = new DevToolsLoader();
|
||||
let require = loader.require;
|
||||
|
||||
let variableFileContents = require("raw!devtools/client/themes/variables.css");
|
||||
ok(variableFileContents.length > 0, "raw browserRequire worked");
|
||||
}
|
|
@ -25,6 +25,7 @@ support-files =
|
|||
[test_console_filtering.js]
|
||||
[test_prettifyCSS.js]
|
||||
[test_require_lazy.js]
|
||||
[test_require_raw.js]
|
||||
[test_require.js]
|
||||
[test_stack.js]
|
||||
[test_defer.js]
|
||||
|
|
|
@ -764,11 +764,12 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
|
|||
event.pressure = aPressure;
|
||||
event.inputSource = aInputSourceArg;
|
||||
event.pointerId = aPointerId;
|
||||
event.width = aWidth;
|
||||
event.height = aHeight;
|
||||
event.mWidth = aWidth;
|
||||
event.mHeight = aHeight;
|
||||
event.tiltX = aTiltX;
|
||||
event.tiltY = aTiltY;
|
||||
event.isPrimary = (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
|
||||
event.mIsPrimary =
|
||||
(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
|
||||
event.mClickCount = aClickCount;
|
||||
event.mTime = PR_IntervalNow();
|
||||
event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
|
||||
|
|
|
@ -3834,10 +3834,10 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
|
|||
newPointerEvent =
|
||||
new WidgetPointerEvent(aMouseEvent->IsTrusted(), aMessage,
|
||||
aMouseEvent->mWidget);
|
||||
newPointerEvent->isPrimary = sourcePointer->isPrimary;
|
||||
newPointerEvent->mIsPrimary = sourcePointer->mIsPrimary;
|
||||
newPointerEvent->pointerId = sourcePointer->pointerId;
|
||||
newPointerEvent->width = sourcePointer->width;
|
||||
newPointerEvent->height = sourcePointer->height;
|
||||
newPointerEvent->mWidth = sourcePointer->mWidth;
|
||||
newPointerEvent->mHeight = sourcePointer->mHeight;
|
||||
newPointerEvent->inputSource = sourcePointer->inputSource;
|
||||
newPointerEvent->relatedTarget =
|
||||
nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId)
|
||||
|
|
|
@ -87,13 +87,13 @@ PointerEvent::Constructor(EventTarget* aOwner,
|
|||
|
||||
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
|
||||
widgetEvent->pointerId = aParam.mPointerId;
|
||||
widgetEvent->width = aParam.mWidth;
|
||||
widgetEvent->height = aParam.mHeight;
|
||||
widgetEvent->mWidth = aParam.mWidth;
|
||||
widgetEvent->mHeight = aParam.mHeight;
|
||||
widgetEvent->pressure = aParam.mPressure;
|
||||
widgetEvent->tiltX = aParam.mTiltX;
|
||||
widgetEvent->tiltY = aParam.mTiltY;
|
||||
widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType);
|
||||
widgetEvent->isPrimary = aParam.mIsPrimary;
|
||||
widgetEvent->mIsPrimary = aParam.mIsPrimary;
|
||||
widgetEvent->buttons = aParam.mButtons;
|
||||
|
||||
e->SetTrusted(trusted);
|
||||
|
@ -126,13 +126,13 @@ PointerEvent::PointerId()
|
|||
int32_t
|
||||
PointerEvent::Width()
|
||||
{
|
||||
return mEvent->AsPointerEvent()->width;
|
||||
return mEvent->AsPointerEvent()->mWidth;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::Height()
|
||||
{
|
||||
return mEvent->AsPointerEvent()->height;
|
||||
return mEvent->AsPointerEvent()->mHeight;
|
||||
}
|
||||
|
||||
float
|
||||
|
@ -156,7 +156,7 @@ PointerEvent::TiltY()
|
|||
bool
|
||||
PointerEvent::IsPrimary()
|
||||
{
|
||||
return mEvent->AsPointerEvent()->isPrimary;
|
||||
return mEvent->AsPointerEvent()->mIsPrimary;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -369,7 +369,7 @@ HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
|||
mType == NS_FORM_BUTTON_RESET)) {
|
||||
InternalFormEvent event(true,
|
||||
(mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit);
|
||||
event.originator = this;
|
||||
event.mOriginator = this;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell =
|
||||
|
|
|
@ -687,7 +687,7 @@ HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
|||
if (aEvent) {
|
||||
InternalFormEvent* formEvent = aEvent->AsFormEvent();
|
||||
if (formEvent) {
|
||||
nsIContent* originator = formEvent->originator;
|
||||
nsIContent* originator = formEvent->mOriginator;
|
||||
if (originator) {
|
||||
if (!originator->IsHTMLElement()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
|
|
@ -4556,7 +4556,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
|||
if (mForm) {
|
||||
InternalFormEvent event(true,
|
||||
(mType == NS_FORM_INPUT_RESET) ? eFormReset : eFormSubmit);
|
||||
event.originator = this;
|
||||
event.mOriginator = this;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell =
|
||||
|
|
|
@ -114,13 +114,10 @@ ProcessHandle GetCurrentProcessHandle();
|
|||
bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
|
||||
|
||||
// Converts a PID to a process handle. On Windows the handle is opened
|
||||
// with more access rights and must only be used by trusted code. Parameter
|
||||
// error can be used to get the error code in opening the process handle.
|
||||
// with more access rights and must only be used by trusted code.
|
||||
// You have to close returned handle using CloseProcessHandle. Returns true
|
||||
// on success.
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
||||
ProcessHandle* handle,
|
||||
int64_t* error = nullptr);
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
|
||||
|
||||
// Closes the process handle opened by OpenProcessHandle.
|
||||
void CloseProcessHandle(ProcessHandle process);
|
||||
|
|
|
@ -49,14 +49,9 @@ bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
||||
ProcessHandle* handle,
|
||||
int64_t* error) {
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||
// On POSIX permissions are checked for each operation on process,
|
||||
// not when opening a "handle".
|
||||
if (error) {
|
||||
*error = 0;
|
||||
}
|
||||
return OpenProcessHandle(pid, handle);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,9 +86,7 @@ bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
||||
ProcessHandle* handle,
|
||||
int64_t* error) {
|
||||
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||
ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
|
||||
PROCESS_TERMINATE |
|
||||
PROCESS_QUERY_INFORMATION |
|
||||
|
@ -97,9 +95,6 @@ bool OpenPrivilegedProcessHandle(ProcessId pid,
|
|||
FALSE, pid);
|
||||
|
||||
if (result == NULL) {
|
||||
if (error) {
|
||||
*error = GetLastError();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1151,43 +1151,47 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
|||
mChildTask = child_task;
|
||||
#endif
|
||||
|
||||
OpenPrivilegedHandle(base::GetProcId(process));
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CREATED;
|
||||
lock.Notify();
|
||||
if (!OpenPrivilegedHandle(base::GetProcId(process))
|
||||
#ifdef XP_WIN
|
||||
// If we failed in opening the process handle, try harder by duplicating
|
||||
// one.
|
||||
&& !::DuplicateHandle(::GetCurrentProcess(), process,
|
||||
::GetCurrentProcess(), &mChildProcessHandle,
|
||||
PROCESS_DUP_HANDLE | PROCESS_TERMINATE |
|
||||
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ |
|
||||
SYNCHRONIZE,
|
||||
FALSE, 0)
|
||||
#endif
|
||||
) {
|
||||
NS_RUNTIMEABORT("cannot open handle to child process");
|
||||
}
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CREATED;
|
||||
lock.Notify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
GeckoChildProcessHost::OpenPrivilegedHandle(base::ProcessId aPid)
|
||||
{
|
||||
if (mChildProcessHandle) {
|
||||
MOZ_ASSERT(aPid == base::GetProcId(mChildProcessHandle));
|
||||
return;
|
||||
}
|
||||
int64_t error = 0;
|
||||
if (!base::OpenPrivilegedProcessHandle(aPid, &mChildProcessHandle, &error)) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("LastError"),
|
||||
nsPrintfCString ("%lld", error));
|
||||
#endif
|
||||
NS_RUNTIMEABORT("can't open handle to child process");
|
||||
return true;
|
||||
}
|
||||
|
||||
return base::OpenPrivilegedProcessHandle(aPid, &mChildProcessHandle);
|
||||
}
|
||||
|
||||
void
|
||||
GeckoChildProcessHost::OnChannelConnected(int32_t peer_pid)
|
||||
{
|
||||
OpenPrivilegedHandle(peer_pid);
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CONNECTED;
|
||||
lock.Notify();
|
||||
if (!OpenPrivilegedHandle(peer_pid)) {
|
||||
NS_RUNTIMEABORT("can't open handle to child process");
|
||||
}
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CONNECTED;
|
||||
lock.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1254,7 +1258,9 @@ bool
|
|||
GeckoExistingProcessHost::PerformAsyncLaunch(StringVector aExtraOpts,
|
||||
base::ProcessArchitecture aArch)
|
||||
{
|
||||
OpenPrivilegedHandle(base::GetProcId(mExistingProcessHandle));
|
||||
if (!OpenPrivilegedHandle(base::GetProcId(mExistingProcessHandle))) {
|
||||
NS_RUNTIMEABORT("can't open handle to child process");
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CREATED;
|
||||
|
|
|
@ -173,7 +173,7 @@ protected:
|
|||
task_t mChildTask;
|
||||
#endif
|
||||
|
||||
void OpenPrivilegedHandle(base::ProcessId aPid);
|
||||
bool OpenPrivilegedHandle(base::ProcessId aPid);
|
||||
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
|
||||
|
|
|
@ -6839,14 +6839,16 @@ PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
|
|||
// In this case we have to know information about available mouse pointers
|
||||
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||
gActivePointersIds->Put(mouseEvent->pointerId,
|
||||
new PointerInfo(false, mouseEvent->inputSource, true));
|
||||
new PointerInfo(false, mouseEvent->inputSource,
|
||||
true));
|
||||
}
|
||||
break;
|
||||
case ePointerDown:
|
||||
// In this case we switch pointer to active state
|
||||
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||
gActivePointersIds->Put(pointerEvent->pointerId,
|
||||
new PointerInfo(true, pointerEvent->inputSource, pointerEvent->isPrimary));
|
||||
new PointerInfo(true, pointerEvent->inputSource,
|
||||
pointerEvent->mIsPrimary));
|
||||
}
|
||||
break;
|
||||
case ePointerUp:
|
||||
|
@ -6854,14 +6856,17 @@ PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
|
|||
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||
if(pointerEvent->inputSource != nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
|
||||
gActivePointersIds->Put(pointerEvent->pointerId,
|
||||
new PointerInfo(false, pointerEvent->inputSource, pointerEvent->isPrimary));
|
||||
new PointerInfo(false,
|
||||
pointerEvent->inputSource,
|
||||
pointerEvent->mIsPrimary));
|
||||
} else {
|
||||
gActivePointersIds->Remove(pointerEvent->pointerId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eMouseExitFromWidget:
|
||||
// In this case we have to remove information about disappeared mouse pointers
|
||||
// In this case we have to remove information about disappeared mouse
|
||||
// pointers
|
||||
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||
gActivePointersIds->Remove(mouseEvent->pointerId);
|
||||
}
|
||||
|
@ -7205,12 +7210,12 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell,
|
|||
|
||||
WidgetPointerEvent event(touchEvent->IsTrusted(), pointerMessage,
|
||||
touchEvent->mWidget);
|
||||
event.isPrimary = i == 0;
|
||||
event.mIsPrimary = i == 0;
|
||||
event.pointerId = touch->Identifier();
|
||||
event.mRefPoint = touch->mRefPoint;
|
||||
event.mModifiers = touchEvent->mModifiers;
|
||||
event.width = touch->RadiusX();
|
||||
event.height = touch->RadiusY();
|
||||
event.mWidth = touch->RadiusX();
|
||||
event.mHeight = touch->RadiusY();
|
||||
event.tiltX = touch->tiltX;
|
||||
event.tiltY = touch->tiltY;
|
||||
event.mTime = touchEvent->mTime;
|
||||
|
|
|
@ -563,6 +563,9 @@ MediaPipeline::AttachTransport_s()
|
|||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
transport_->Attach(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ class MediaPipeline : public sigslot::has_slots<> {
|
|||
: pipeline_(pipeline),
|
||||
sts_thread_(pipeline->sts_thread_) {}
|
||||
|
||||
void Attach(MediaPipeline *pipeline) { pipeline_ = pipeline; }
|
||||
void Detach() { pipeline_ = nullptr; }
|
||||
MediaPipeline *pipeline() const { return pipeline_; }
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ firefox-ui-functional-local:
|
|||
treeherder-symbol: tc-Fxfn-l(en-US)
|
||||
max-run-time: 5400
|
||||
tier: 1
|
||||
docker-image: {"in-tree": "desktop1604-test"}
|
||||
mozharness:
|
||||
script: mozharness/scripts/firefox_ui_tests/functional.py
|
||||
config:
|
||||
|
@ -67,6 +68,7 @@ firefox-ui-functional-remote:
|
|||
treeherder-symbol: tc-Fxfn-r(en-US)
|
||||
max-run-time: 5400
|
||||
tier: 2
|
||||
docker-image: {"in-tree": "desktop1604-test"}
|
||||
mozharness:
|
||||
script: mozharness/scripts/firefox_ui_tests/functional.py
|
||||
config:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# 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/.
|
||||
|
||||
from errors import MarionetteException, TimeoutException
|
||||
from errors import MarionetteException
|
||||
from functools import wraps
|
||||
import socket
|
||||
import sys
|
||||
|
@ -40,13 +40,16 @@ def do_process_check(func, always=False):
|
|||
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except (MarionetteException, socket.error, IOError) as e:
|
||||
except (MarionetteException, IOError) as e:
|
||||
exc, val, tb = sys.exc_info()
|
||||
|
||||
# In case of socket failures force a shutdown of the application
|
||||
if type(e) in (socket.error, socket.timeout):
|
||||
m.force_shutdown()
|
||||
|
||||
if not isinstance(e, MarionetteException) or type(e) is MarionetteException:
|
||||
if not always:
|
||||
check_for_crash()
|
||||
if not isinstance(e, MarionetteException) or type(e) is TimeoutException:
|
||||
m.force_shutdown()
|
||||
raise exc, val, tb
|
||||
finally:
|
||||
if always:
|
||||
|
|
|
@ -49,7 +49,10 @@ class MarionetteException(Exception):
|
|||
st = "".join(["\t%s\n" % x for x in self.stacktrace.splitlines()])
|
||||
msg += "\nstacktrace:\n%s" % st
|
||||
|
||||
return "".join(traceback.format_exception(self.__class__, msg, tb)).strip()
|
||||
if tb:
|
||||
msg += ': ' + "".join(traceback.format_tb(tb))
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
class ElementNotSelectableException(MarionetteException):
|
||||
|
|
|
@ -173,7 +173,7 @@ class GeckoInstance(object):
|
|||
def restart(self, prefs=None, clean=True):
|
||||
self.close(restart=True)
|
||||
|
||||
if clean:
|
||||
if clean and self.profile:
|
||||
self.profile.cleanup()
|
||||
self.profile = None
|
||||
|
||||
|
@ -221,11 +221,9 @@ class FennecInstance(GeckoInstance):
|
|||
self.runner.device.connect()
|
||||
self.runner.start()
|
||||
except Exception as e:
|
||||
message = 'Error possibly due to runner or device args.'
|
||||
e.args += (message,)
|
||||
if hasattr(e, 'strerror') and e.strerror:
|
||||
e.strerror = ', '.join([e.strerror, message])
|
||||
raise e
|
||||
exc, val, tb = sys.exc_info()
|
||||
message = 'Error possibly due to runner or device args: {}'
|
||||
raise exc, message.format(e.message), tb
|
||||
# gecko_log comes from logcat when running with device/emulator
|
||||
logcat_args = {
|
||||
'filterspec': 'Gecko',
|
||||
|
|
|
@ -543,6 +543,7 @@ class Marionette(object):
|
|||
TIMEOUT_PAGE = 'page load'
|
||||
DEFAULT_SOCKET_TIMEOUT = 360
|
||||
DEFAULT_STARTUP_TIMEOUT = 120
|
||||
DEFAULT_SHUTDOWN_TIMEOUT = 65 # Firefox will kill hanging threads after 60s
|
||||
|
||||
def __init__(self, host='localhost', port=2828, app=None, bin=None,
|
||||
baseurl=None, timeout=None, socket_timeout=DEFAULT_SOCKET_TIMEOUT,
|
||||
|
@ -616,7 +617,7 @@ class Marionette(object):
|
|||
if self.session:
|
||||
try:
|
||||
self.delete_session()
|
||||
except (errors.MarionetteException, socket.error, IOError):
|
||||
except (errors.MarionetteException, IOError):
|
||||
# These exceptions get thrown if the Marionette server
|
||||
# hit an exception/died or the connection died. We can
|
||||
# do no further server-side cleanup in this case.
|
||||
|
@ -648,7 +649,7 @@ class Marionette(object):
|
|||
@do_process_check
|
||||
def raise_for_port(self, port_obtained):
|
||||
if not port_obtained:
|
||||
raise IOError("Timed out waiting for port!")
|
||||
raise socket.timeout("Timed out waiting for port {}!".format(self.port))
|
||||
|
||||
@do_process_check
|
||||
def _send_message(self, name, params=None, key=None):
|
||||
|
@ -684,7 +685,8 @@ class Marionette(object):
|
|||
self.session = None
|
||||
self.window = None
|
||||
self.client.close()
|
||||
raise errors.TimeoutException("Connection timed out")
|
||||
|
||||
raise
|
||||
|
||||
res, err = msg.result, msg.error
|
||||
if err:
|
||||
|
@ -754,17 +756,19 @@ class Marionette(object):
|
|||
if self.instance:
|
||||
exc, val, tb = sys.exc_info()
|
||||
|
||||
returncode = self.instance.runner.returncode
|
||||
# Give the application some time to shutdown
|
||||
returncode = self.instance.runner.wait(timeout=self.DEFAULT_STARTUP_TIMEOUT)
|
||||
if returncode is None:
|
||||
self.instance.runner.stop()
|
||||
message = 'Process killed because the connection was lost'
|
||||
self.cleanup()
|
||||
message = ('Process killed because the connection to Marionette server is lost.'
|
||||
' Check gecko.log for errors')
|
||||
else:
|
||||
message = 'Process died with returncode "{returncode}"'
|
||||
message = 'Process has been closed (Exit code: {returncode})'
|
||||
|
||||
if exc:
|
||||
message += ' (Reason: {reason})'
|
||||
|
||||
raise exc, message.format(returncode=returncode, reason=val), tb
|
||||
raise IOError, message.format(returncode=returncode, reason=val), tb
|
||||
|
||||
@staticmethod
|
||||
def convert_keys(*string):
|
||||
|
@ -993,8 +997,8 @@ class Marionette(object):
|
|||
: param prefs: A dictionary whose keys are preference names.
|
||||
"""
|
||||
if not self.instance:
|
||||
raise errors.MarionetteException("enforce_gecko_prefs can only be called "
|
||||
"on gecko instances launched by Marionette")
|
||||
raise errors.MarionetteException("enforce_gecko_prefs() can only be called "
|
||||
"on Gecko instances launched by Marionette")
|
||||
pref_exists = True
|
||||
self.set_context(self.CONTEXT_CHROME)
|
||||
for pref, value in prefs.iteritems():
|
||||
|
@ -1027,13 +1031,14 @@ class Marionette(object):
|
|||
self.start_session()
|
||||
self.reset_timeouts()
|
||||
|
||||
@do_process_check
|
||||
def quit_in_app(self):
|
||||
"""
|
||||
This will terminate the currently running instance.
|
||||
"""
|
||||
if not self.instance:
|
||||
raise errors.MarionetteException("quit_in_app can only be called "
|
||||
"on gecko instances launched by Marionette")
|
||||
raise errors.MarionetteException("quit_in_app() can only be called "
|
||||
"on Gecko instances launched by Marionette")
|
||||
# Values here correspond to constants in nsIAppStartup.
|
||||
# See http://mzl.la/1X0JZsC
|
||||
restart_flags = [
|
||||
|
@ -1042,7 +1047,14 @@ class Marionette(object):
|
|||
]
|
||||
self._send_message("quitApplication", {"flags": restart_flags})
|
||||
self.client.close()
|
||||
self.raise_for_port(self.wait_for_port())
|
||||
|
||||
try:
|
||||
self.raise_for_port(self.wait_for_port())
|
||||
except socket.timeout:
|
||||
if self.instance.runner.returncode is not None:
|
||||
exc, val, tb = sys.exc_info()
|
||||
self.cleanup()
|
||||
raise exc, 'Requested restart of the application was aborted', tb
|
||||
|
||||
def restart(self, clean=False, in_app=False):
|
||||
"""
|
||||
|
@ -1057,11 +1069,11 @@ class Marionette(object):
|
|||
by killing the process.
|
||||
"""
|
||||
if not self.instance:
|
||||
raise errors.MarionetteException("restart can only be called "
|
||||
"on gecko instances launched by Marionette")
|
||||
raise errors.MarionetteException("restart() can only be called "
|
||||
"on Gecko instances launched by Marionette")
|
||||
if in_app:
|
||||
if clean:
|
||||
raise ValueError
|
||||
raise ValueError("An in_app restart cannot be triggered with the clean flag set")
|
||||
self.quit_in_app()
|
||||
else:
|
||||
self.delete_session()
|
||||
|
@ -1463,8 +1475,13 @@ class Marionette(object):
|
|||
:param ms: A number value specifying the timeout length in
|
||||
milliseconds (ms)
|
||||
"""
|
||||
if timeout_type not in [self.TIMEOUT_SEARCH, self.TIMEOUT_SCRIPT, self.TIMEOUT_PAGE]:
|
||||
raise ValueError("Unknown timeout type: %s" % timeout_type)
|
||||
timeout_types = (self.TIMEOUT_PAGE,
|
||||
self.TIMEOUT_SCRIPT,
|
||||
self.TIMEOUT_SEARCH,
|
||||
)
|
||||
if timeout_type not in timeout_types:
|
||||
raise ValueError("Unknown timeout type: {0} (should be one "
|
||||
"of {1})".format(timeout_type, timeout_types))
|
||||
body = {"type": timeout_type, "ms": ms}
|
||||
self._send_message("timeouts", body)
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import datetime
|
||||
import errno
|
||||
import json
|
||||
import socket
|
||||
import time
|
||||
|
@ -119,7 +118,6 @@ class TcpTransport(object):
|
|||
Supported protocol levels are 1 and above.
|
||||
"""
|
||||
max_packet_length = 4096
|
||||
connection_lost_msg = "Connection to Marionette server is lost. Check gecko.log for errors."
|
||||
|
||||
def __init__(self, addr, port, socket_timeout=360.0):
|
||||
"""If `socket_timeout` is `0` or `0.0`, non-blocking socket mode
|
||||
|
@ -176,7 +174,7 @@ class TcpTransport(object):
|
|||
pass
|
||||
else:
|
||||
if not chunk:
|
||||
raise IOError(self.connection_lost_msg)
|
||||
raise socket.error("No data received over socket")
|
||||
|
||||
sep = data.find(":")
|
||||
if sep > -1:
|
||||
|
@ -203,7 +201,7 @@ class TcpTransport(object):
|
|||
|
||||
bytes_to_recv = int(length) - len(remaining)
|
||||
|
||||
raise socket.timeout("connection timed out after %ds" % self.socket_timeout)
|
||||
raise socket.timeout("Connection timed out after %ds" % self.socket_timeout)
|
||||
|
||||
def connect(self):
|
||||
"""Connect to the server and process the hello message we expect
|
||||
|
@ -246,19 +244,12 @@ class TcpTransport(object):
|
|||
|
||||
totalsent = 0
|
||||
while totalsent < len(payload):
|
||||
try:
|
||||
sent = self.sock.send(payload[totalsent:])
|
||||
if sent == 0:
|
||||
raise IOError("socket error after sending %d of %d bytes" %
|
||||
(totalsent, len(payload)))
|
||||
else:
|
||||
totalsent += sent
|
||||
|
||||
except IOError as e:
|
||||
if e.errno == errno.EPIPE:
|
||||
raise IOError("%s: %s" % (str(e), self.connection_lost_msg))
|
||||
else:
|
||||
raise e
|
||||
sent = self.sock.send(payload[totalsent:])
|
||||
if sent == 0:
|
||||
raise IOError("Socket error after sending %d of %d bytes" %
|
||||
(totalsent, len(payload)))
|
||||
else:
|
||||
totalsent += sent
|
||||
|
||||
def respond(self, obj):
|
||||
"""Send a response to a command. This can be an arbitrary JSON
|
||||
|
|
|
@ -121,9 +121,9 @@ class Wait(object):
|
|||
while not until(self.clock, self.end):
|
||||
try:
|
||||
rv = condition(self.marionette)
|
||||
except (KeyboardInterrupt, SystemExit) as e:
|
||||
raise e
|
||||
except self.exceptions as e:
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except self.exceptions:
|
||||
last_exc = sys.exc_info()
|
||||
|
||||
if not rv:
|
||||
|
|
|
@ -128,9 +128,9 @@ this.GeckoDriver = function(appName, stopSignal) {
|
|||
|
||||
this.sessionCapabilities = {
|
||||
// mandated capabilities
|
||||
"browserName": Services.appinfo.name,
|
||||
"browserName": Services.appinfo.name.toLowerCase(),
|
||||
"browserVersion": Services.appinfo.version,
|
||||
"platformName": Services.sysinfo.getProperty("name"),
|
||||
"platformName": Services.sysinfo.getProperty("name").toLowerCase(),
|
||||
"platformVersion": Services.sysinfo.getProperty("version"),
|
||||
"specificationLevel": 0,
|
||||
|
||||
|
|
|
@ -616,9 +616,9 @@ class BaseMarionetteTestRunner(object):
|
|||
with open(path) as f:
|
||||
data.append(json.loads(f.read()))
|
||||
except ValueError as e:
|
||||
raise Exception("JSON file (%s) is not properly "
|
||||
"formatted: %s" % (os.path.abspath(path),
|
||||
e.message))
|
||||
exc, val, tb = sys.exc_info()
|
||||
msg = "JSON file ({0}) is not properly formatted: {1}"
|
||||
raise exc, msg.format(os.path.abspath(path), e.message), tb
|
||||
return data
|
||||
|
||||
@property
|
||||
|
@ -669,11 +669,7 @@ class BaseMarionetteTestRunner(object):
|
|||
"""
|
||||
self._bin = path
|
||||
self.tests = []
|
||||
if hasattr(self, 'marionette') and self.marionette:
|
||||
self.marionette.cleanup()
|
||||
if self.marionette.instance:
|
||||
self.marionette.instance = None
|
||||
self.marionette = None
|
||||
self.cleanup()
|
||||
|
||||
def reset_test_stats(self):
|
||||
self.passed = 0
|
||||
|
@ -737,8 +733,10 @@ class BaseMarionetteTestRunner(object):
|
|||
connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
connection.connect((host,int(port)))
|
||||
connection.close()
|
||||
except Exception, e:
|
||||
raise Exception("Connection attempt to %s:%s failed with error: %s" %(host,port,e))
|
||||
except Exception as e:
|
||||
exc, val, tb = sys.exc_info()
|
||||
msg = "Connection attempt to {0}:{1} failed with error: {2}"
|
||||
raise exc, msg.format(host, port, e), tb
|
||||
if self.workspace:
|
||||
kwargs['workspace'] = self.workspace_path
|
||||
return kwargs
|
||||
|
@ -896,16 +894,17 @@ setReq.onerror = function() {
|
|||
# we want to display current test results.
|
||||
# so we keep the exception to raise it later.
|
||||
interrupted = sys.exc_info()
|
||||
except:
|
||||
# For any other exception we return immediately and have to
|
||||
# cleanup running processes
|
||||
self.cleanup()
|
||||
raise
|
||||
|
||||
try:
|
||||
self._print_summary(tests)
|
||||
self.record_crash()
|
||||
self.elapsedtime = time.time() - start_time
|
||||
|
||||
if self.marionette.instance:
|
||||
self.marionette.instance.close()
|
||||
self.marionette.instance = None
|
||||
self.marionette.cleanup()
|
||||
|
||||
for run_tests in self.mixin_run_tests:
|
||||
run_tests(tests)
|
||||
if self.shuffle:
|
||||
|
@ -918,6 +917,8 @@ setReq.onerror = function() {
|
|||
if not interrupted:
|
||||
raise
|
||||
finally:
|
||||
self.cleanup()
|
||||
|
||||
# reraise previous interruption now
|
||||
if interrupted:
|
||||
raise interrupted[0], interrupted[1], interrupted[2]
|
||||
|
@ -1090,10 +1091,16 @@ setReq.onerror = function() {
|
|||
self.run_test_set(self.tests)
|
||||
|
||||
def cleanup(self):
|
||||
if self.httpd:
|
||||
if hasattr(self, 'httpd') and self.httpd:
|
||||
self.httpd.stop()
|
||||
self.httpd = None
|
||||
|
||||
if hasattr(self, 'marionette') and self.marionette:
|
||||
if self.marionette.instance:
|
||||
self.marionette.instance.close()
|
||||
self.marionette.instance = None
|
||||
|
||||
if self.marionette:
|
||||
self.marionette.cleanup()
|
||||
self.marionette = None
|
||||
|
||||
__del__ = cleanup
|
||||
|
|
|
@ -11,7 +11,7 @@ class FixtureServer(object):
|
|||
|
||||
def __init__(self, root, host="127.0.0.1", port=0):
|
||||
if not os.path.isdir(root):
|
||||
raise Exception("Server root is not a valid path: %s" % root)
|
||||
raise IOError("Server root is not a valid path: %s" % root)
|
||||
self.root = root
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
@ -44,7 +44,7 @@ class FixtureServer(object):
|
|||
|
||||
def get_url(self, path="/"):
|
||||
if not self.alive:
|
||||
raise "Server not started"
|
||||
raise Exception("Server not started")
|
||||
return self._server.get_url(path)
|
||||
|
||||
@property
|
||||
|
|
|
@ -31,8 +31,8 @@ class Server(object):
|
|||
break
|
||||
|
||||
if not os.path.isfile(path) and exec_not_on_path:
|
||||
raise Exception("Browsermob-Proxy binary couldn't be found in path"
|
||||
" provided: %s" % path)
|
||||
raise IOError("Browsermob-Proxy binary couldn't be found in path"
|
||||
" provided: %s" % path)
|
||||
|
||||
self.path = path
|
||||
self.port = options.get('port', 8080)
|
||||
|
|
|
@ -12,7 +12,7 @@ class TestAboutPages(MarionetteTestCase):
|
|||
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
if self.marionette.session_capabilities['platformName'] == 'Darwin':
|
||||
if self.marionette.session_capabilities['platformName'] == 'darwin':
|
||||
self.mod_key = Keys.META
|
||||
else:
|
||||
self.mod_key = Keys.CONTROL
|
||||
|
|
|
@ -15,7 +15,7 @@ class TestCapabilities(MarionetteTestCase):
|
|||
self.appinfo = self.marionette.execute_script(
|
||||
"return Services.appinfo")
|
||||
self.os_name = self.marionette.execute_script(
|
||||
"return Services.sysinfo.getProperty('name')")
|
||||
"return Services.sysinfo.getProperty('name')").lower()
|
||||
self.os_version = self.marionette.execute_script(
|
||||
"return Services.sysinfo.getProperty('version')")
|
||||
|
||||
|
@ -30,7 +30,7 @@ class TestCapabilities(MarionetteTestCase):
|
|||
self.assertIn("platformVersion", self.caps)
|
||||
self.assertIn("specificationLevel", self.caps)
|
||||
|
||||
self.assertEqual(self.caps["browserName"], self.appinfo["name"])
|
||||
self.assertEqual(self.caps["browserName"], self.appinfo["name"].lower())
|
||||
self.assertEqual(self.caps["browserVersion"], self.appinfo["version"])
|
||||
self.assertEqual(self.caps["platformName"], self.os_name)
|
||||
self.assertEqual(self.caps["platformVersion"], self.os_version)
|
||||
|
@ -78,12 +78,12 @@ class TestCapabilities(MarionetteTestCase):
|
|||
capabilities = {"desiredCapabilities": {"browserName": "ChocolateCake"}}
|
||||
self.marionette.start_session(capabilities)
|
||||
caps = self.marionette.session_capabilities
|
||||
self.assertEqual(caps["browserName"], self.appinfo["name"],
|
||||
"This should have appname not ChocolateCake")
|
||||
self.assertEqual(caps["browserName"], self.appinfo["name"].lower(),
|
||||
"This should have appname not ChocolateCake.")
|
||||
|
||||
def test_we_can_pass_in_required_capabilities_on_session_start(self):
|
||||
self.marionette.delete_session()
|
||||
capabilities = {"requiredCapabilities": {"browserName": self.appinfo["name"]}}
|
||||
capabilities = {"requiredCapabilities": {"browserName": self.appinfo["name"].lower()}}
|
||||
self.marionette.start_session(capabilities)
|
||||
caps = self.marionette.session_capabilities
|
||||
self.assertIn("browserName", caps)
|
||||
|
|
|
@ -38,7 +38,6 @@ class TestErrors(marionette_test.MarionetteTestCase):
|
|||
self.assertIn(message, r)
|
||||
self.assertIn(", caused by %r" % cause[0], r)
|
||||
self.assertIn("\nstacktrace:\n\tfirst\n\tsecond", r)
|
||||
self.assertIn("MarionetteException:", r)
|
||||
|
||||
def test_cause_string(self):
|
||||
exc = errors.MarionetteException(cause="foo")
|
||||
|
|
|
@ -11,7 +11,7 @@ from marionette_driver.by import By
|
|||
class TestKeyActions(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
||||
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||
self.mod_key = Keys.META
|
||||
else:
|
||||
self.mod_key = Keys.CONTROL
|
||||
|
|
|
@ -11,7 +11,7 @@ from marionette_driver.by import By
|
|||
class TestMouseAction(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
||||
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||
self.mod_key = Keys.META
|
||||
else:
|
||||
self.mod_key = Keys.CONTROL
|
||||
|
|
|
@ -11,6 +11,12 @@ from marionette_driver.by import By
|
|||
|
||||
|
||||
class TestTimeouts(MarionetteTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
self.marionette.reset_timeouts()
|
||||
|
||||
MarionetteTestCase.tearDown(self)
|
||||
|
||||
def test_pagetimeout_notdefinetimeout_pass(self):
|
||||
test_html = self.marionette.absolute_url("test.html")
|
||||
self.marionette.navigate(test_html)
|
||||
|
@ -62,3 +68,8 @@ class TestTimeouts(MarionetteTestCase):
|
|||
var callback = arguments[arguments.length - 1];
|
||||
setTimeout(function() { callback(true); }, 500);
|
||||
"""))
|
||||
|
||||
def test_invalid_timeout_type(self):
|
||||
self.assertRaises(ValueError, self.marionette.timeouts, "foobar", 1000)
|
||||
self.assertRaises(ValueError, self.marionette.timeouts, 42, 1000)
|
||||
self.assertRaises(MarionetteException, self.marionette.timeouts, "page load", "foobar")
|
||||
|
|
|
@ -58,7 +58,7 @@ class TestTyping(MarionetteTestCase):
|
|||
|
||||
def testCutAndPasteShortcuts(self):
|
||||
# test that modifier keys work via copy/paste shortcuts
|
||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
||||
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||
mod_key = Keys.META
|
||||
else:
|
||||
mod_key = Keys.CONTROL
|
||||
|
|
|
@ -12,7 +12,7 @@ class TestWindowHandles(MarionetteTestCase):
|
|||
def test_new_tab_window_handles(self):
|
||||
|
||||
keys = []
|
||||
if self.marionette.session_capabilities['platformName'] == 'Darwin':
|
||||
if self.marionette.session_capabilities['platformName'] == 'darwin':
|
||||
keys.append(Keys.META)
|
||||
else:
|
||||
keys.append(Keys.CONTROL)
|
||||
|
|
|
@ -126,7 +126,7 @@ function registerSelf() {
|
|||
if (register[0]) {
|
||||
let {id, remotenessChange} = register[0][0];
|
||||
capabilities = register[0][2];
|
||||
isB2G = capabilities.platformName == "B2G";
|
||||
isB2G = capabilities.platformName == "b2g";
|
||||
listenerId = id;
|
||||
if (typeof id != "undefined") {
|
||||
// check if we're the main process
|
||||
|
|
|
@ -66,7 +66,7 @@ class Puppeteer(object):
|
|||
|
||||
:returns: Platform name
|
||||
"""
|
||||
return self.marionette.session_capabilities['platformName'].lower()
|
||||
return self.marionette.session_capabilities['platformName']
|
||||
|
||||
@use_class_as_property('api.prefs.Preferences')
|
||||
def prefs(self):
|
||||
|
|
|
@ -13,7 +13,7 @@ class Keys(marionette_driver.keys.Keys):
|
|||
self.marionette_getter = marionette_getter
|
||||
|
||||
caps = self.marionette_getter().session_capabilities
|
||||
self.isDarwin = caps['platformName'] == 'DARWIN'
|
||||
self.isDarwin = caps['platformName'] == 'darwin'
|
||||
|
||||
@property
|
||||
def ACCEL(self):
|
||||
|
|
|
@ -398,7 +398,7 @@ class BaseWindow(BaseLib):
|
|||
Defaults to `False`.
|
||||
"""
|
||||
|
||||
platform = self.marionette.session_capabilities['platformName'].lower()
|
||||
platform = self.marionette.session_capabilities['platformName']
|
||||
|
||||
keymap = {
|
||||
'accel': Keys.META if platform == 'darwin' else Keys.CONTROL,
|
||||
|
|
|
@ -283,8 +283,14 @@ FinderHighlighter.prototype = {
|
|||
* Optional, defaults to the finder window.
|
||||
* @param {nsIDOMRange} skipRange A range that should not be removed from the
|
||||
* find selection.
|
||||
* @param {nsIDOMEvent} event When called from an event handler, this will
|
||||
* be the triggering event.
|
||||
*/
|
||||
hide(window = null, skipRange = null) {
|
||||
hide(window = null, skipRange = null, event = null) {
|
||||
// Do not hide on anything but a left-click.
|
||||
if (event && event.type == "click" && event.button !== 0)
|
||||
return;
|
||||
|
||||
window = window || this.finder._getWindow();
|
||||
|
||||
let doc = window.document;
|
||||
|
@ -836,12 +842,11 @@ FinderHighlighter.prototype = {
|
|||
|
||||
this._highlightListeners = [
|
||||
this._scheduleRepaintOfMask.bind(this, window),
|
||||
this.hide.bind(this, window)
|
||||
this.hide.bind(this, window, null)
|
||||
];
|
||||
window.addEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
||||
window.addEventListener("mousedown", this._highlightListeners[1]);
|
||||
window.addEventListener("click", this._highlightListeners[1]);
|
||||
window.addEventListener("resize", this._highlightListeners[1]);
|
||||
window.addEventListener("touchstart", this._highlightListeners[1]);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -854,9 +859,8 @@ FinderHighlighter.prototype = {
|
|||
return;
|
||||
|
||||
window.removeEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
||||
window.removeEventListener("mousedown", this._highlightListeners[1]);
|
||||
window.removeEventListener("click", this._highlightListeners[1]);
|
||||
window.removeEventListener("resize", this._highlightListeners[1]);
|
||||
window.removeEventListener("touchstart", this._highlightListeners[1]);
|
||||
|
||||
this._highlightListeners = null;
|
||||
},
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
* mozilla::InternalFormEvent
|
||||
*
|
||||
* We hold the originating form control for form submit and reset events.
|
||||
* originator is a weak pointer (does not hold a strong reference).
|
||||
* mOriginator is a weak pointer (does not hold a strong reference).
|
||||
******************************************************************************/
|
||||
|
||||
class InternalFormEvent : public WidgetEvent
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
|
||||
InternalFormEvent(bool aIsTrusted, EventMessage aMessage)
|
||||
: WidgetEvent(aIsTrusted, aMessage, eFormEventClass)
|
||||
, originator(nullptr)
|
||||
, mOriginator(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
nsIContent *originator;
|
||||
nsIContent* mOriginator;
|
||||
|
||||
void AssignFormEventData(const InternalFormEvent& aEvent, bool aCopyTargets)
|
||||
{
|
||||
AssignEventData(aEvent, aCopyTargets);
|
||||
|
||||
// Don't copy originator due to a weak pointer.
|
||||
// Don't copy mOriginator due to a weak pointer.
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -666,9 +666,9 @@ class WidgetPointerEvent : public WidgetMouseEvent
|
|||
friend class mozilla::dom::PBrowserChild;
|
||||
|
||||
WidgetPointerEvent()
|
||||
: width(0)
|
||||
, height(0)
|
||||
, isPrimary(true)
|
||||
: mWidth(0)
|
||||
, mHeight(0)
|
||||
, mIsPrimary(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -677,17 +677,17 @@ public:
|
|||
|
||||
WidgetPointerEvent(bool aIsTrusted, EventMessage aMsg, nsIWidget* w)
|
||||
: WidgetMouseEvent(aIsTrusted, aMsg, w, ePointerEventClass, eReal)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, isPrimary(true)
|
||||
, mWidth(0)
|
||||
, mHeight(0)
|
||||
, mIsPrimary(true)
|
||||
{
|
||||
}
|
||||
|
||||
explicit WidgetPointerEvent(const WidgetMouseEvent& aEvent)
|
||||
: WidgetMouseEvent(aEvent)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, isPrimary(true)
|
||||
, mWidth(0)
|
||||
, mHeight(0)
|
||||
, mIsPrimary(true)
|
||||
{
|
||||
mClass = ePointerEventClass;
|
||||
}
|
||||
|
@ -704,9 +704,9 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
bool isPrimary;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
bool mIsPrimary;
|
||||
|
||||
// XXX Not tested by test_assign_event_data.html
|
||||
void AssignPointerEventData(const WidgetPointerEvent& aEvent,
|
||||
|
@ -714,9 +714,9 @@ public:
|
|||
{
|
||||
AssignMouseEventData(aEvent, aCopyTargets);
|
||||
|
||||
width = aEvent.width;
|
||||
height = aEvent.height;
|
||||
isPrimary = aEvent.isPrimary;
|
||||
mWidth = aEvent.mWidth;
|
||||
mHeight = aEvent.mHeight;
|
||||
mIsPrimary = aEvent.mIsPrimary;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -287,11 +287,11 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
|
|||
{
|
||||
WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
|
||||
WriteParam(aMsg, aParam.pointerId);
|
||||
WriteParam(aMsg, aParam.width);
|
||||
WriteParam(aMsg, aParam.height);
|
||||
WriteParam(aMsg, aParam.mWidth);
|
||||
WriteParam(aMsg, aParam.mHeight);
|
||||
WriteParam(aMsg, aParam.tiltX);
|
||||
WriteParam(aMsg, aParam.tiltY);
|
||||
WriteParam(aMsg, aParam.isPrimary);
|
||||
WriteParam(aMsg, aParam.mIsPrimary);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
|
@ -299,11 +299,11 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
|
|||
bool rv =
|
||||
ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->pointerId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->width) &&
|
||||
ReadParam(aMsg, aIter, &aResult->height) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mWidth) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mHeight) &&
|
||||
ReadParam(aMsg, aIter, &aResult->tiltX) &&
|
||||
ReadParam(aMsg, aIter, &aResult->tiltY) &&
|
||||
ReadParam(aMsg, aIter, &aResult->isPrimary);
|
||||
ReadParam(aMsg, aIter, &aResult->mIsPrimary);
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче