# 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 from tempfile import NamedTemporaryFile as tempfile import six from six.moves.urllib.parse import quote from marionette_driver import By, errors, expected from marionette_driver.wait import Wait from marionette_harness import MarionetteTestCase, skip single = "data:text/html,{}".format(quote("")) multiple = "data:text/html,{}".format(quote("")) upload = lambda url: "data:text/html,{}".format( quote( """
""".format( 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_file_names(input) self.assertEqual(len(files), 1) self.assertFileNamesEqual(files, exp) def test_sets_multiple_files(self): self.marionette.navigate(multiple) input = self.input exp = None with tempfile() as a, tempfile() as b: input.send_keys(a.name) input.send_keys(b.name) exp = [a.name, b.name] files = self.get_file_names(input) self.assertEqual(len(files), 2) self.assertFileNamesEqual(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_file_names(input) self.assertEqual(len(files), 2) self.assertFileNamesEqual(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 tempfile() as a, tempfile() as 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"))) url = self.marionette.get_url() with tempfile() as f: f.write(six.ensure_binary("camembert")) f.flush() self.input.send_keys(f.name) self.submit.click() Wait(self.marionette, timeout=self.marionette.timeout.page_load).until( lambda m: m.get_url() != url, message="URL didn't change after submitting a file upload", ) self.assertIn("multipart/form-data", self.body.text) def test_change_event(self): self.marionette.navigate(single) self.marionette.execute_script( """ window.changeEvs = []; let el = arguments[arguments.length - 1]; el.addEventListener("change", ev => window.changeEvs.push(ev)); console.log(window.changeEvs.length); """, script_args=(self.input,), sandbox=None, ) with tempfile() as f: self.input.send_keys(f.name) nevs = self.marionette.execute_script( "return window.changeEvs.length", sandbox=None ) self.assertEqual(1, nevs) def find_inputs(self): return self.marionette.find_elements(By.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_file_names(self, el): fl = self.get_files(el) return [f["name"] for f in fl] def get_files(self, el): return self.marionette.execute_script( "return arguments[0].files", script_args=[el] ) def assertFileNamesEqual(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)