mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Backed out changeset 93166201fca0 (bug 941085) for Gip failures.
CLOSED TREE
This commit is contained in:
parent
4ed9fdd437
commit
d2e5e61478
@ -18,6 +18,7 @@ from runner import (
|
||||
MarionetteTestResult,
|
||||
MarionetteTextTestRunner,
|
||||
MemoryEnduranceTestCaseMixin,
|
||||
MozHttpd,
|
||||
OptionParser,
|
||||
TestManifest,
|
||||
TestResult,
|
||||
|
@ -5,7 +5,7 @@
|
||||
from base import (
|
||||
B2GTestResultMixin, BaseMarionetteOptions, BaseMarionetteTestRunner,
|
||||
Marionette, MarionetteTest, MarionetteTestResult, MarionetteTextTestRunner,
|
||||
OptionParser, TestManifest, TestResult, TestResultCollection
|
||||
MozHttpd, OptionParser, TestManifest, TestResult, TestResultCollection
|
||||
)
|
||||
from mixins import (
|
||||
B2GTestCaseMixin, B2GTestResultMixin, EnduranceOptionsMixin,
|
||||
|
@ -20,13 +20,12 @@ from manifestparser import TestManifest
|
||||
from manifestparser.filters import tags
|
||||
from marionette_driver.marionette import Marionette
|
||||
from mixins.b2g import B2GTestResultMixin, get_b2g_pid, get_dm
|
||||
from mozhttpd import MozHttpd
|
||||
from mozlog.structured.structuredlog import get_default_logger
|
||||
from moztest.adapters.unit import StructuredTestRunner, StructuredTestResult
|
||||
from moztest.results import TestResultCollection, TestResult, relevant_line
|
||||
import mozversion
|
||||
|
||||
import httpd
|
||||
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
@ -639,6 +638,24 @@ class BaseMarionetteTestRunner(object):
|
||||
self.skipped = 0
|
||||
self.failures = []
|
||||
|
||||
def start_httpd(self, need_external_ip):
|
||||
if self.server_root is None or os.path.isdir(self.server_root):
|
||||
host = '127.0.0.1'
|
||||
if need_external_ip:
|
||||
host = moznetwork.get_ip()
|
||||
docroot = self.server_root or os.path.join(os.path.dirname(here), 'www')
|
||||
if not os.path.isdir(docroot):
|
||||
raise Exception('Server root %s is not a valid path' % docroot)
|
||||
self.httpd = MozHttpd(host=host,
|
||||
port=0,
|
||||
docroot=docroot)
|
||||
self.httpd.start()
|
||||
self.marionette.baseurl = 'http://%s:%d/' % (host, self.httpd.httpd.server_port)
|
||||
self.logger.info('running webserver on %s' % self.marionette.baseurl)
|
||||
else:
|
||||
self.marionette.baseurl = self.server_root
|
||||
self.logger.info('using content from %s' % self.marionette.baseurl)
|
||||
|
||||
def _build_kwargs(self):
|
||||
kwargs = {
|
||||
'device_serial': self.device_serial,
|
||||
@ -763,9 +780,7 @@ setReq.onerror = function() {
|
||||
|
||||
if not self.httpd:
|
||||
self.logger.info("starting httpd")
|
||||
self.httpd = self.create_httpd(need_external_ip)
|
||||
self.marionette.baseurl = self.httpd.get_url()
|
||||
self.logger.info("running httpd on %s" % self.marionette.baseurl)
|
||||
self.start_httpd(need_external_ip)
|
||||
|
||||
for test in tests:
|
||||
self.add_test(test)
|
||||
@ -846,15 +861,6 @@ setReq.onerror = function() {
|
||||
|
||||
self.logger.suite_end()
|
||||
|
||||
def create_httpd(self, need_external_ip):
|
||||
ip = "127.0.0.1"
|
||||
if need_external_ip:
|
||||
ip = moznetwork.get_ip()
|
||||
root = self.server_root or os.path.join(os.path.dirname(here), "www")
|
||||
rv = httpd.FixtureServer(root, host=ip)
|
||||
rv.start()
|
||||
return rv
|
||||
|
||||
def add_test(self, test, expected='pass', test_container=None):
|
||||
filepath = os.path.abspath(test)
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
import os
|
||||
|
||||
from mozhttpd import MozHttpd
|
||||
|
||||
|
||||
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)
|
||||
self.root = root
|
||||
self.host = host
|
||||
self.port = port
|
||||
self._server = None
|
||||
|
||||
def start(self, block=False):
|
||||
if self.alive:
|
||||
return
|
||||
self._server = MozHttpd(host=self.host, port=self.port, docroot=self.root, urlhandlers=[
|
||||
{"method": "POST", "path": "/file_upload", "function": upload_handler}])
|
||||
self._server.start(block=block)
|
||||
self.port = self._server.httpd.server_port
|
||||
self.base_url = self.get_url()
|
||||
|
||||
def stop(self):
|
||||
if not self.alive:
|
||||
return
|
||||
self._server.stop()
|
||||
self._server = None
|
||||
|
||||
@property
|
||||
def alive(self):
|
||||
return self._server is not None
|
||||
|
||||
def get_url(self, path="/"):
|
||||
if not self.alive:
|
||||
raise "Server not started"
|
||||
return self._server.get_url(path)
|
||||
|
||||
|
||||
def upload_handler(query, postdata=None):
|
||||
return (200, {}, query.headers.getheader("Content-Type"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
root = os.path.join(os.path.dirname(here), "www")
|
||||
httpd = FixtureServer(root, port=2829)
|
||||
print "Started fixture server on http://%s:%d/" % (httpd.host, httpd.port)
|
||||
try:
|
||||
httpd.start(True)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
@ -1,135 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
import contextlib
|
||||
import urllib
|
||||
|
||||
from tempfile import NamedTemporaryFile as tempfile
|
||||
|
||||
from marionette import MarionetteTestCase, skip
|
||||
from marionette_driver import By, errors, expected
|
||||
from marionette_driver.wait import Wait
|
||||
|
||||
|
||||
single = "data:text/html,%s" % urllib.quote("<input type=file>")
|
||||
multiple = "data:text/html,%s" % urllib.quote("<input type=file multiple>")
|
||||
upload = lambda url: "data:text/html,%s" % urllib.quote("""
|
||||
<form action='%s' method=post enctype='multipart/form-data'>
|
||||
<input type=file>
|
||||
<input type=submit>
|
||||
</form>""" % url)
|
||||
|
||||
|
||||
class TestFileUpload(MarionetteTestCase):
|
||||
|
||||
def test_sets_one_file(self):
|
||||
self.marionette.navigate(single)
|
||||
input = self.input
|
||||
|
||||
exp = None
|
||||
with tempfile() as f:
|
||||
input.send_keys(f.name)
|
||||
exp = [f.name]
|
||||
|
||||
files = self.get_files(input)
|
||||
self.assertEqual(len(files), 1)
|
||||
self.assertFilesEqual(files, exp)
|
||||
|
||||
def test_sets_multiple_files(self):
|
||||
self.marionette.navigate(multiple)
|
||||
input = self.input
|
||||
|
||||
exp = None
|
||||
with contextlib.nested(tempfile(), tempfile()) as (a, b):
|
||||
input.send_keys(a.name)
|
||||
input.send_keys(b.name)
|
||||
exp = [a.name, b.name]
|
||||
|
||||
files = self.get_files(input)
|
||||
self.assertEqual(len(files), 2)
|
||||
self.assertFilesEqual(files, exp)
|
||||
|
||||
def test_sets_multiple_indentical_files(self):
|
||||
self.marionette.navigate(multiple)
|
||||
input = self.input
|
||||
|
||||
exp = []
|
||||
with tempfile() as f:
|
||||
input.send_keys(f.name)
|
||||
input.send_keys(f.name)
|
||||
exp = f.name
|
||||
|
||||
files = self.get_files(input)
|
||||
self.assertEqual(len(files), 2)
|
||||
self.assertFilesEqual(files, exp)
|
||||
|
||||
def test_clear_file(self):
|
||||
self.marionette.navigate(single)
|
||||
input = self.input
|
||||
|
||||
with tempfile() as f:
|
||||
input.send_keys(f.name)
|
||||
|
||||
self.assertEqual(len(self.get_files(input)), 1)
|
||||
input.clear()
|
||||
self.assertEqual(len(self.get_files(input)), 0)
|
||||
|
||||
def test_clear_files(self):
|
||||
self.marionette.navigate(multiple)
|
||||
input = self.input
|
||||
|
||||
with contextlib.nested(tempfile(), tempfile()) as (a, b):
|
||||
input.send_keys(a.name)
|
||||
input.send_keys(b.name)
|
||||
|
||||
self.assertEqual(len(self.get_files(input)), 2)
|
||||
input.clear()
|
||||
self.assertEqual(len(self.get_files(input)), 0)
|
||||
|
||||
def test_illegal_file(self):
|
||||
self.marionette.navigate(single)
|
||||
with self.assertRaisesRegexp(errors.MarionetteException, "File not found"):
|
||||
self.input.send_keys("rochefort")
|
||||
|
||||
def test_upload(self):
|
||||
self.marionette.navigate(
|
||||
upload(self.marionette.absolute_url("file_upload")))
|
||||
|
||||
with tempfile() as f:
|
||||
f.write("camembert")
|
||||
f.flush()
|
||||
self.input.send_keys(f.name)
|
||||
self.submit.click()
|
||||
|
||||
self.assertIn("multipart/form-data", self.body.text)
|
||||
|
||||
def find_inputs(self):
|
||||
return self.marionette.find_elements("tag name", "input")
|
||||
|
||||
@property
|
||||
def input(self):
|
||||
return self.find_inputs()[0]
|
||||
|
||||
@property
|
||||
def submit(self):
|
||||
return self.find_inputs()[1]
|
||||
|
||||
@property
|
||||
def body(self):
|
||||
return Wait(self.marionette).until(
|
||||
expected.element_present(By.TAG_NAME, "body"))
|
||||
|
||||
def get_files(self, el):
|
||||
# This is horribly complex because (1) Marionette doesn't serialise arrays properly,
|
||||
# and (2) accessing File.name in the content JS throws a permissions
|
||||
# error.
|
||||
fl = self.marionette.execute_script(
|
||||
"return arguments[0].files", script_args=[el])
|
||||
return [f["name"] for f in [v for k, v in fl.iteritems() if k.isdigit()]]
|
||||
|
||||
def assertFilesEqual(self, act, exp):
|
||||
# File array returned from browser doesn't contain full path names,
|
||||
# this cuts off the path of the expected files.
|
||||
filenames = [f.rsplit("/", 0)[-1] for f in act]
|
||||
self.assertListEqual(filenames, act)
|
@ -154,6 +154,3 @@ b2g = false
|
||||
b2g = false
|
||||
[test_teardown_context_preserved.py]
|
||||
b2g = false
|
||||
[test_file_upload.py]
|
||||
b2g = false
|
||||
skip-if = os == "win" # http://bugs.python.org/issue14574
|
||||
|
@ -884,9 +884,8 @@ GeckoDriver.prototype.executeScriptInSandbox = function(
|
||||
directInject,
|
||||
async,
|
||||
timeout) {
|
||||
if (directInject && async && (timeout == null || timeout == 0)) {
|
||||
if (directInject && async && (timeout == null || timeout == 0))
|
||||
throw new TimeoutError("Please set a timeout");
|
||||
}
|
||||
|
||||
if (this.importedScripts.exists()) {
|
||||
let stream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
@ -2308,10 +2307,6 @@ GeckoDriver.prototype.getElementRect = function(cmd, resp) {
|
||||
GeckoDriver.prototype.sendKeysToElement = function(cmd, resp) {
|
||||
let {id, value} = cmd.parameters;
|
||||
|
||||
if (!value) {
|
||||
throw new IllegalArgumentError(`Expected character sequence: ${value}`);
|
||||
}
|
||||
|
||||
switch (this.context) {
|
||||
case Context.CHROME:
|
||||
let win = this.getCurrentWindow();
|
||||
@ -2327,36 +2322,7 @@ GeckoDriver.prototype.sendKeysToElement = function(cmd, resp) {
|
||||
break;
|
||||
|
||||
case Context.CONTENT:
|
||||
let err;
|
||||
let listener = function(msg) {
|
||||
this.mm.removeMessageListener("Marionette:setElementValue", listener);
|
||||
|
||||
let val = msg.data.value;
|
||||
let el = msg.objects.element;
|
||||
let win = this.getCurrentWindow();
|
||||
|
||||
if (el.type == "file") {
|
||||
Cu.importGlobalProperties(["File"]);
|
||||
let fs = Array.prototype.slice.call(el.files);
|
||||
let file;
|
||||
try {
|
||||
file = new File(val);
|
||||
} catch (e) {
|
||||
err = new IllegalArgumentError(`File not found: ${val}`);
|
||||
}
|
||||
fs.push(file);
|
||||
el.mozSetFileArray(fs);
|
||||
} else {
|
||||
el.value = val;
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
this.mm.addMessageListener("Marionette:setElementValue", listener);
|
||||
yield this.listener.sendKeysToElement({id: id, value: value});
|
||||
this.mm.removeMessageListener("Marionette:setElementValue", listener);
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -10,7 +10,6 @@ const errors = [
|
||||
"ElementNotVisibleError",
|
||||
"FrameSendFailureError",
|
||||
"FrameSendNotInitializedError",
|
||||
"IllegalArgumentError",
|
||||
"InvalidElementStateError",
|
||||
"JavaScriptError",
|
||||
"NoAlertOpenError",
|
||||
@ -159,14 +158,6 @@ this.FrameSendNotInitializedError = function(frame) {
|
||||
};
|
||||
FrameSendNotInitializedError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.IllegalArgumentError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "IllegalArgumentError";
|
||||
this.status = "illegal argument";
|
||||
this.code = 13; // unknown error
|
||||
};
|
||||
IllegalArgumentError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.InvalidElementStateError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidElementStateError";
|
||||
@ -308,7 +299,6 @@ const errorObjs = [
|
||||
this.ElementNotVisibleError,
|
||||
this.FrameSendFailureError,
|
||||
this.FrameSendNotInitializedError,
|
||||
this.IllegalArgumentError,
|
||||
this.InvalidElementStateError,
|
||||
this.JavaScriptError,
|
||||
this.NoAlertOpenError,
|
||||
|
@ -35,10 +35,9 @@ let isB2G = false;
|
||||
|
||||
let marionetteTestName;
|
||||
let winUtil = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let listenerId = null; // unique ID of this listener
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let listenerId = null; //unique ID of this listener
|
||||
let curFrame = content;
|
||||
let isRemoteBrowser = () => curFrame.contentWindow !== null;
|
||||
let previousFrame = null;
|
||||
let elementManager = new ElementManager([]);
|
||||
let accessibility = new Accessibility();
|
||||
@ -1549,39 +1548,11 @@ function isElementSelected(msg) {
|
||||
*/
|
||||
function sendKeysToElement(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
let val = msg.json.value;
|
||||
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
if (el.type == "file") {
|
||||
let p = val.join("");
|
||||
let keysToSend = msg.json.value;
|
||||
|
||||
// for some reason using mozSetFileArray doesn't work with e10s
|
||||
// enabled (probably a bug), but a workaround is to elevate the element's
|
||||
// privileges with SpecialPowers
|
||||
//
|
||||
// this extra branch can be removed when the e10s bug 1149998 is fixed
|
||||
if (isRemoteBrowser()) {
|
||||
let fs = Array.prototype.slice.call(el.files);
|
||||
let file;
|
||||
try {
|
||||
file = new File(p);
|
||||
} catch (e) {
|
||||
let err = new IllegalArgumentError(`File not found: ${val}`);
|
||||
sendError(err.message, err.code, err.stack, command_id);
|
||||
return;
|
||||
}
|
||||
fs.push(file);
|
||||
|
||||
let wel = new SpecialPowers(utils.window).wrap(el);
|
||||
wel.mozSetFileArray(fs);
|
||||
} else {
|
||||
sendSyncMessage("Marionette:setElementValue", {value: p}, {element: el});
|
||||
}
|
||||
|
||||
sendOk(command_id);
|
||||
} else {
|
||||
utils.sendKeysToElement(curFrame, el, val, sendOk, sendError, command_id);
|
||||
}
|
||||
utils.sendKeysToElement(curFrame, el, keysToSend, sendOk, sendError, command_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1611,13 +1582,10 @@ function clearElement(msg) {
|
||||
let command_id = msg.json.command_id;
|
||||
try {
|
||||
let el = elementManager.getKnownElement(msg.json.id, curFrame);
|
||||
if (el.type == "file") {
|
||||
el.value = null;
|
||||
} else {
|
||||
utils.clearElement(el);
|
||||
}
|
||||
utils.clearElement(el);
|
||||
sendOk(command_id);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
sendError(e.message, e.code, e.stack, command_id);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user