summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/entries-api
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/entries-api
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/entries-api')
-rw-r--r--testing/web-platform/tests/entries-api/META.yml4
-rw-r--r--testing/web-platform/tests/entries-api/README.md9
-rw-r--r--testing/web-platform/tests/entries-api/errors-manual.html61
-rw-r--r--testing/web-platform/tests/entries-api/file-webkitRelativePath-manual.html33
-rw-r--r--testing/web-platform/tests/entries-api/filesystem-manual.html40
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryentry-attributes-manual.html37
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryentry-createReader-manual.html23
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryentry-getDirectory-manual.html128
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryentry-getFile-manual.html115
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryentry-getParent-manual.html17
-rw-r--r--testing/web-platform/tests/entries-api/filesystemdirectoryreader-manual.html77
-rw-r--r--testing/web-platform/tests/entries-api/filesystementry-attributes-manual.html29
-rw-r--r--testing/web-platform/tests/entries-api/filesystementry-getParent-manual.html27
-rw-r--r--testing/web-platform/tests/entries-api/filesystemfileentry-attributes-manual.html37
-rw-r--r--testing/web-platform/tests/entries-api/filesystemfileentry-file-manual.html26
-rw-r--r--testing/web-platform/tests/entries-api/filesystemfileentry-getParent-manual.html17
-rw-r--r--testing/web-platform/tests/entries-api/idlharness-manual.window.js46
-rw-r--r--testing/web-platform/tests/entries-api/idlharness.window.js15
-rw-r--r--testing/web-platform/tests/entries-api/support.js138
-rw-r--r--testing/web-platform/tests/entries-api/support/a/b/c/3.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/a/b/c/d/1.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/a/b/c/d/2.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/upload.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/upload/file.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/upload/subdir/1.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/upload/subdir/2.txt0
-rw-r--r--testing/web-platform/tests/entries-api/support/upload/subdir/3.txt0
27 files changed, 879 insertions, 0 deletions
diff --git a/testing/web-platform/tests/entries-api/META.yml b/testing/web-platform/tests/entries-api/META.yml
new file mode 100644
index 0000000000..69f68452f2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/META.yml
@@ -0,0 +1,4 @@
+spec: https://wicg.github.io/entries-api/
+suggested_reviewers:
+ - aliams
+ - inexorabletash
diff --git a/testing/web-platform/tests/entries-api/README.md b/testing/web-platform/tests/entries-api/README.md
new file mode 100644
index 0000000000..7c08ba837b
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/README.md
@@ -0,0 +1,9 @@
+Tests for the [Files and Directory Entries API](https://github.com/wicg/entries-api)
+
+* [Explainer](https://github.com/WICG/entries-api/blob/gh-pages/EXPLAINER.md)
+* [Draft Specification](https://wicg.github.io/entries-api/)
+
+Unfortunately, most of the tests are **manual** and require drag-and-drop of test
+data files, which can be found in the `entries-api/support` directory. The tests
+can be run via [wpt.live](http://wpt.live/entries-api/), but a local clone
+of the repo is required for access to the test data files.
diff --git a/testing/web-platform/tests/entries-api/errors-manual.html b/testing/web-platform/tests/entries-api/errors-manual.html
new file mode 100644
index 0000000000..f7134982af
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/errors-manual.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: Errors manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ entry.getFile(
+ NOT_FOUND_PATHS[0],
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(typeof error.name, 'string', 'Error has name property');
+ assert_equals(typeof error.message, 'string', 'Error has message property');
+ assert_equals(error.name, 'NotFoundError', 'error is NotFoundError');
+ t.done();
+ }));
+}, 'Errors - NotFoundError');
+
+entry_test((t, entry) => {
+ entry.getFile(
+ DIR_PATHS[0],
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(typeof error.name, 'string', 'Error has name property');
+ assert_equals(typeof error.message, 'string', 'Error has message property');
+ assert_equals(error.name, 'TypeMismatchError', 'error is TypeMismatchError');
+ t.done();
+ }));
+}, 'Errors - TypeMismatchError');
+
+entry_test((t, entry) => {
+ entry.getFile(
+ FILE_PATHS[0],
+ {create: true},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(typeof error.name, 'string', 'Error has name property');
+ assert_equals(typeof error.message, 'string', 'Error has message property');
+ assert_equals(error.name, 'SecurityError', 'error is SecurityError');
+ t.done();
+ }));
+}, 'Errors - SecurityError');
+
+entry_test((t, entry) => {
+ const reader = entry.createReader();
+ reader.readEntries(() => {}, t.unreached_func('readEntries should succeed'));
+ reader.readEntries(
+ t.unreached_func('readEntries() should fail if already reading'),
+ t.step_func(error => {
+ assert_equals(typeof error.name, 'string', 'Error has name property');
+ assert_equals(typeof error.message, 'string', 'Error has message property');
+ assert_equals(error.name, 'InvalidStateError', 'error is InvalidStateError');
+ t.done();
+ }));
+}, 'Errors - InvalidStateError');
+</script>
diff --git a/testing/web-platform/tests/entries-api/file-webkitRelativePath-manual.html b/testing/web-platform/tests/entries-api/file-webkitRelativePath-manual.html
new file mode 100644
index 0000000000..695ccc47c3
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/file-webkitRelativePath-manual.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: File webitRelativePath manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#file-interface">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+Select the <b>support/a</b> directory:
+
+<input type=file multiple webkitdirectory>
+
+<script>
+setup({explicit_timeout: true});
+
+const filesPromise = new Promise(resolve => {
+ const elem = document.querySelector('input[type=file]');
+ elem.addEventListener('change', e => resolve(elem.files));
+});
+
+promise_test(t => filesPromise.then(files => {
+ assert_equals(files.length, 3, 'expected 3 items');
+ files = Array.from(files).sort(
+ (a, b) => a.name < b.name ? -1 : b.name < a.name ? 1 : 0);
+ assert_equals(files[0].name, '1.txt');
+ assert_equals(files[1].name, '2.txt');
+ assert_equals(files[2].name, '3.txt');
+ assert_equals(files[0].webkitRelativePath, 'a/b/c/d/1.txt');
+ assert_equals(files[1].webkitRelativePath, 'a/b/c/d/2.txt');
+ assert_equals(files[2].webkitRelativePath, 'a/b/c/3.txt');
+
+}), 'webkitRelativePath is shortest common ancestor');
+
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystem-manual.html b/testing/web-platform/tests/entries-api/filesystem-manual.html
new file mode 100644
index 0000000000..9e84b10c08
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystem-manual.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystem manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-domfilesystem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ const fs = entry.filesystem;
+
+ assert_idl_attribute(fs, 'name', 'has name attribute');
+ assert_equals(typeof fs.name, 'string', 'name is a string');
+
+ assert_idl_attribute(fs, 'root', 'has root attribute');
+ assert_true(fs.root.isDirectory,
+ 'FileSystem root is a directory entry');
+
+ assert_equals(fs.root.name, '', 'root name is empty string');
+
+ assert_equals(fs.root.fullPath, '/', 'root path is /');
+
+ t.done();
+
+}, 'FileSystem - API');
+
+entry_test((t, entry) => {
+ const fs = entry.filesystem;
+
+ getChildEntry(entry, 'file.txt', t.step_func(child => {
+ const cfs = child.filesystem;
+ assert_not_equals(fs, cfs.filesystem, 'FileSystem objects do not have object identity');
+ assert_equals(fs.name, cfs.name, 'FileSystem names match');
+
+ t.done();
+ }), t.unreached_func('child entry file.txt should be present'));
+
+}, 'FileSystem - name consistency and object identity');
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryentry-attributes-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-attributes-manual.html
new file mode 100644
index 0000000000..9422c014ac
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-attributes-manual.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryEntry attributes manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-directoryentry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ assert_idl_attribute(entry, 'isFile', 'FileSystemDirectoryEntry has isFile attribute');
+ assert_equals(typeof entry.isFile, 'boolean', 'isFile is boolean');
+
+ assert_idl_attribute(entry, 'isDirectory', 'FileSystemDirectoryEntry has isDirectory attribute');
+ assert_equals(typeof entry.isDirectory, 'boolean', 'isDirectory is boolean');
+
+ assert_idl_attribute(entry, 'name', 'FileSystemDirectoryEntry has name attribute');
+ assert_equals(typeof entry.name, 'string', 'name is a string');
+
+ assert_idl_attribute(entry, 'fullPath', 'FileSystemDirectoryEntry has fullPath attribute');
+ assert_equals(typeof entry.fullPath, 'string', 'fullPath is a string');
+
+ assert_idl_attribute(entry, 'filesystem', 'FileSystemDirectoryEntry has filesystem attribute');
+ assert_equals(typeof entry.filesystem, 'object', 'filesystem is an object');
+
+ t.done();
+}, 'FileSystemDirectoryEntry - attribute types');
+
+entry_test((t, entry) => {
+ assert_false(entry.isFile, 'isFile is false');
+ assert_true(entry.isDirectory, 'isDirectory is true');
+ assert_equals(entry.name, 'upload', 'expected directory was uploaded');
+ assert_equals(entry.fullPath, '/upload', 'directory is child of root directory');
+ t.done();
+}, 'FileSystemDirectoryEntry - attribute values');
+
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryentry-createReader-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-createReader-manual.html
new file mode 100644
index 0000000000..f9369c6f74
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-createReader-manual.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryEntry createReader() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-directoryentry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+
+ assert_idl_attribute(entry, 'createReader', 'FileSystemDirectoryEntry has createReader');
+ assert_equals(typeof entry.createReader, 'function', 'createReader() is a method');
+
+ t.done();
+}, 'FileSystemDirectoryEntry - createReader()');
+
+entry_test((t, entry) => {
+ assert_not_equals(entry.createReader(), entry.createReader(),
+ 'createReader() returns a new object each time');
+ t.done();
+}, 'FileSystemDirectoryEntry - createReader() distinct objects');
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getDirectory-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getDirectory-manual.html
new file mode 100644
index 0000000000..d78bb66df7
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getDirectory-manual.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryEntry.getDirectory() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getdirectory">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ assert_idl_attribute(entry, 'getDirectory', 'FileSystemDirectoryEntry has getDirectory');
+ assert_equals(typeof entry.getDirectory, 'function', 'getDirectory() is a method');
+
+ t.done();
+}, 'FileSystemDirectoryEntry - getDirectory()');
+
+INVALID_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {},
+ t.unreached_func('getDirectory should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'TypeMismatchError',
+ 'getDirectory() should fail if given invalid path');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getDirectory() - invalid path: ' + JSON.stringify(path));
+});
+
+EMPTY_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {},
+ t.step_func(dir => {
+ assert_true(dir.isDirectory,
+ 'empty path should yield FileSystemDirectoryEntry');
+ assert_equals(dir.name, entry.name,
+ 'empty path should yield same directory');
+ assert_equals(dir.fullPath, entry.fullPath,
+ 'empty path should yield same directory');
+ t.done();
+ }),
+ t.unreached_func('getDirectory should not fail')
+ );
+ }, 'FileSystemDirectoryEntry.getDirectory() - empty path: '
+ + JSON.stringify(path) || 'undefined');
+});
+
+DIR_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {create: true},
+ t.unreached_func('getDirectory should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'SecurityError',
+ 'getDirectory() should fail with security error if ' +
+ 'create option is set');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getDirectory() - {create:true}: ' + path);
+});
+
+NOT_FOUND_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {},
+ t.unreached_func('getDirectory should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'NotFoundError',
+ 'getDirectory() should fail with not found');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getDirectory() - not found: ' + path);
+});
+
+FILE_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {},
+ t.unreached_func('getDirectory should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'TypeMismatchError',
+ 'getDirectory() should fail if type is file');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getDirectory() - directory: ' + path);
+});
+
+DIR_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ path,
+ {},
+ t.step_func(e => {
+ assert_false(e.isFile);
+ assert_true(e.isDirectory);
+ assert_equals(e.name, 'subdir');
+ t.done();
+ }),
+ t.unreached_func('getDirectory should not fail')
+ );
+ }, 'FileSystemDirectoryEntry.getDirectory() - directory: ' + path);
+});
+
+[
+ {path: '.', name: 'upload'},
+ {path: '/', name: ''}
+].forEach(test_case => {
+ entry_test((t, entry) => {
+ entry.getDirectory(
+ test_case.path,
+ {},
+ t.step_func(e => {
+ assert_false(e.isFile);
+ assert_true(e.isDirectory);
+ assert_equals(e.name, test_case.name);
+ t.done();
+ }),
+ t.unreached_func('getDirectory should not fail')
+ );
+ }, 'FileSystemDirectoryEntry.getDirectory() - directory: ' + test_case.path);
+});
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getFile-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getFile-manual.html
new file mode 100644
index 0000000000..3acd2fbd76
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getFile-manual.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryEntry.getFile() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ assert_idl_attribute(entry, 'getFile', 'FileSystemDirectoryEntry has getFile');
+ assert_equals(typeof entry.getFile, 'function', 'getFile() is a method');
+
+ t.done();
+}, 'FileSystemDirectoryEntry - getFile()');
+
+INVALID_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'TypeMismatchError',
+ 'getFile() should fail if given invalid path');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getFile() - invalid path: ' + JSON.stringify(path));
+});
+
+EMPTY_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'TypeMismatchError',
+ 'getFile() on empty path should fail because the ' +
+ 'path resolves to the directory itself');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getFile() - empty path: ' + JSON.stringify(path) || 'undefined');
+});
+
+FILE_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {create: true},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'SecurityError',
+ 'getFile() should fail with security error if ' +
+ 'create option is set');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getFile() - {create:true}: ' + path);
+});
+
+NOT_FOUND_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'NotFoundError',
+ 'getFile() should fail with not found');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getFile() - not found: ' + path);
+});
+
+DIR_PATHS.concat(['/', '.']).forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {},
+ t.unreached_func('getFile should fail'),
+ t.step_func(error => {
+ assert_equals(error.name, 'TypeMismatchError',
+ 'getFile() should fail if type is directory');
+ t.done();
+ }));
+ }, 'FileSystemDirectoryEntry.getFile() - directory: ' + path);
+});
+
+FILE_PATHS.forEach(path => {
+ entry_test((t, entry) => {
+ entry.getFile(
+ path,
+ {},
+ t.step_func(e => {
+ assert_true(e.isFile);
+ assert_false(e.isDirectory);
+ assert_equals(e.name, 'file.txt');
+ t.done();
+ }),
+ t.unreached_func('getFile should not fail')
+ );
+ }, 'FileSystemDirectoryEntry.getFile() - file: ' + path);
+});
+
+entry_test((t, entry) => {
+ entry.getFile(FILE_PATHS[0], {}, t.step_func(e1 => {
+ entry.getFile(FILE_PATHS[0], {}, t.step_func(e2 => {
+ assert_equals(e1.name, e2.name, 'names should match');
+ assert_equals(e1.fullPath, e2.fullPath, 'names should match');
+ assert_not_equals(e1, e2, 'objects should be distinct');
+ t.done();
+ }), t.unreached_func('getFile should not fail'));
+ }), t.unreached_func('getFile should not fail'));
+}, 'FileSystemDirectoryEntry.getFile() - object identity');
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getParent-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getParent-manual.html
new file mode 100644
index 0000000000..20c2a707d3
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryentry-getParent-manual.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryEntry getParent() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-directoryentry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+
+ assert_idl_attribute(entry, 'getParent', 'FileSystemDirectoryEntry has getParent');
+ assert_equals(typeof entry.getParent, 'function', 'getParent() is a method');
+
+ t.done();
+}, 'FileSystemDirectoryEntry - getParent()');
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemdirectoryreader-manual.html b/testing/web-platform/tests/entries-api/filesystemdirectoryreader-manual.html
new file mode 100644
index 0000000000..55f0fc4e70
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemdirectoryreader-manual.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemDirectoryReader manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-directoryreader">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ const reader = entry.createReader();
+
+ assert_idl_attribute(reader, 'readEntries', 'FileSystemDirectoryReader has readEntries');
+ assert_equals(typeof reader.readEntries, 'function', 'readEntries() is a method');
+
+ t.done();
+}, 'FileSystemDirectoryReader - interface');
+
+
+entry_test((t, entry) => {
+ getChildEntry(entry, 'subdir', t.step_func(dir => {
+ const reader = dir.createReader();
+ assert_equals(typeof reader.readEntries, 'function');
+
+ const found_names = [];
+ const do_chunk = t.step_func(() =>
+ reader.readEntries(t.step_func(entries => {
+
+ if (entries.length > 0) {
+ entries.forEach(t.step_func(entry => found_names.push(entry.name)));
+ do_chunk();
+ return;
+ }
+
+ found_names.sort();
+ assert_array_equals(found_names, ['1.txt', '2.txt', '3.txt'],
+ 'directory contents should match');
+ t.done();
+ })));
+
+ do_chunk();
+ }), t.unreached_func('A child entry should be found'));
+}, 'FileSystemDirectoryReader - basic enumeration');
+
+entry_test((t, entry) => {
+ const reader = entry.createReader();
+ reader.readEntries(() => {}, t.unreached_func('readEntries should succeed'));
+ reader.readEntries(
+ t.unreached_func('readEntries() should fail if already reading'),
+ t.step_func(error => {
+ assert_equals(error.name, 'InvalidStateError', 'invalid state if already reading');
+ t.done();
+ }));
+}, 'FileSystemDirectoryReader - reading flag');
+
+entry_test((t, entry) => {
+ const reader = entry.createReader();
+
+ const do_chunk = t.step_func(() =>
+ reader.readEntries(t.step_func(entries => {
+ if (entries.length > 0) {
+ do_chunk();
+ return;
+ }
+ reader.readEntries(t.step_func(entries => {
+ assert_equals(
+ entries.length, 0,
+ 'calling readEntries() when done should yield and empty sequence');
+ t.done();
+ }));
+ })));
+
+ do_chunk();
+}, 'FileSystemDirectoryReader - done flag');
+
+// TODO: Manual tests where directory contents are changed during the test.
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystementry-attributes-manual.html b/testing/web-platform/tests/entries-api/filesystementry-attributes-manual.html
new file mode 100644
index 0000000000..9f2431b87e
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystementry-attributes-manual.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemEntry attributes manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-entry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ assert_idl_attribute(entry, 'isFile', 'FileSystemEntry has isFile attribute');
+ assert_equals(typeof entry.isFile, 'boolean', 'isFile is boolean');
+
+ assert_idl_attribute(entry, 'isDirectory', 'FileSystemEntry has isDirectory attribute');
+ assert_equals(typeof entry.isDirectory, 'boolean', 'isFile is boolean');
+
+ assert_idl_attribute(entry, 'name', 'FileSystemEntry has name attribute');
+ assert_equals(typeof entry.name, 'string', 'name is a string');
+
+ assert_idl_attribute(entry, 'fullPath', 'FileSystemEntry has fullPath attribute');
+ assert_equals(typeof entry.fullPath, 'string', 'fullPath is a string');
+
+ assert_idl_attribute(entry, 'filesystem', 'FileSystemEntry has filesystem attribute');
+ assert_equals(typeof entry.filesystem, 'object', 'filesystem is an object');
+
+ t.done();
+}, 'FileSystemEntry - attribute types');
+
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystementry-getParent-manual.html b/testing/web-platform/tests/entries-api/filesystementry-getParent-manual.html
new file mode 100644
index 0000000000..7110bdcfbc
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystementry-getParent-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemEntry getParent() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#dom-filesystementry-getparentapi-entry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+entry_test((t, entry) => {
+ assert_idl_attribute(entry, 'getParent', 'FileSystemEntry has getParent method');
+ assert_equals(typeof entry.getParent, 'function', 'FileSystemEntry has a getParent() method');
+
+ assert_equals(entry.getParent(), void 0, 'getParent() arguments are optional');
+
+ entry.getParent(t.step_func(parent => {
+ assert_true(parent.isDirectory, 'parent should be a directory');
+
+ assert_equals(parent.fullPath, '/', 'parent should be root');
+ assert_equals(parent.name, '', 'root name is empty string');
+
+ t.done();
+ }), t.unreached_func('getParent() should not fail'));
+}, 'FileSystemEntry - getParent()');
+
+// TODO: Manual test for getParent() where containing directory is removed before getParent() is called.
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemfileentry-attributes-manual.html b/testing/web-platform/tests/entries-api/filesystemfileentry-attributes-manual.html
new file mode 100644
index 0000000000..113773e82d
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemfileentry-attributes-manual.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemFileEntry attributes manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-entry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+file_entry_test('file.txt', (t, entry) => {
+
+ assert_idl_attribute(entry, 'isFile', 'FileSystemEntry has isFile attribute');
+ assert_equals(typeof entry.isFile, 'boolean', 'isFile is boolean');
+
+ assert_idl_attribute(entry, 'isDirectory', 'FileSystemEntry has isDirectory attribute');
+ assert_equals(typeof entry.isDirectory, 'boolean', 'isFile is boolean');
+
+ assert_idl_attribute(entry, 'name', 'FileSystemEntry has name attribute');
+ assert_equals(typeof entry.name, 'string', 'name is a string');
+
+ assert_idl_attribute(entry, 'fullPath', 'FileSystemEntry has fullPath attribute');
+ assert_equals(typeof entry.fullPath, 'string', 'fullPath is a string');
+
+ assert_idl_attribute(entry, 'filesystem', 'FileSystemEntry has filesystem attribute');
+
+ t.done();
+}, 'FileSystemFileEntry - attribute types');
+
+file_entry_test('file.txt', (t, entry) => {
+ assert_true(entry.isFile);
+ assert_false(entry.isDirectory);
+ assert_equals(entry.name, 'file.txt');
+ assert_equals(entry.fullPath, '/upload/file.txt');
+ t.done();
+}, 'FileSystemFileEntry - attribute values');
+
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemfileentry-file-manual.html b/testing/web-platform/tests/entries-api/filesystemfileentry-file-manual.html
new file mode 100644
index 0000000000..7ac29c0b13
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemfileentry-file-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemFileEntry file() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-entry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+
+file_entry_test('file.txt', (t, entry) => {
+ assert_idl_attribute(entry, 'file', 'FileSystemFileEntry has a file() method');
+ assert_equals(typeof entry.file, 'function', 'FileSystemFileEntry has a file() method');
+
+ assert_throws_js(TypeError, () => entry.file(), 'file() has a required argument');
+ entry.file(t.step_func(file => {
+
+ assert_class_string(file, 'File', 'file() should yield a File');
+ assert_equals(entry.name, file.name, 'entry and file names should match');
+ t.done();
+
+ }), t.unreached_func('file() should not fail'));
+}, 'FileSystemFileEntry - file()');
+
+// TODO: Manual test where file is replaced with directory before file() called
+</script>
diff --git a/testing/web-platform/tests/entries-api/filesystemfileentry-getParent-manual.html b/testing/web-platform/tests/entries-api/filesystemfileentry-getParent-manual.html
new file mode 100644
index 0000000000..fea77348a6
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/filesystemfileentry-getParent-manual.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Entries API: FileSystemFileEntry getParent() manual test</title>
+<link rel=help href="https://wicg.github.io/entries-api/#api-entry">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<script>
+
+file_entry_test('file.txt', (t, entry) => {
+ assert_idl_attribute(entry, 'getParent', 'FileSystemFileEntry has a getParent method');
+ assert_equals(typeof entry.getParent, 'function', 'FileSystemFileEntry has a getParent() method');
+ t.done();
+}, 'FileSystemFileEntry - getParent() method');
+
+</script>
diff --git a/testing/web-platform/tests/entries-api/idlharness-manual.window.js b/testing/web-platform/tests/entries-api/idlharness-manual.window.js
new file mode 100644
index 0000000000..9f2731bf1d
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/idlharness-manual.window.js
@@ -0,0 +1,46 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+// META: script=support.js
+
+'use strict';
+
+let resolve;
+let globalItem;
+let globalEntry;
+
+let entriesPromise = new Promise(r => {
+ resolve = r;
+});
+
+entry_test((t, entry, item) => {
+ assert_true(entry.isDirectory);
+ resolve(getEntriesAsPromise(entry));
+ globalItem = item;
+ globalEntry = entry;
+ t.done();
+});
+
+idl_test(
+ ['entries-api'],
+ ['FileAPI', 'html', 'dom'],
+ async idl_array => {
+ const entries = await entriesPromise;
+ window.samples = {
+ item: globalItem,
+ dirEntry: entries.filter(entry => entry.isDirectory)[0],
+ fileEntry: entries.filter(entry => entry.isFile)[0],
+ fileSystem: globalEntry.filesystem,
+ };
+
+ idl_array.add_objects({
+ File: ['new File([], "example.txt")'],
+ HTMLInputElement: ['document.createElement("input")'],
+ DataTransferItem: ['samples.item'],
+ FileSystemEntry: [],
+ FileSystemDirectoryEntry: ['samples.dirEntry'],
+ FileSystemDirectoryReader: ['samples.dirEntry.createReader()'],
+ FileSystemFileEntry: ['samples.fileEntry'],
+ FileSystem: ['samples.fileSystem'],
+ });
+ }
+);
diff --git a/testing/web-platform/tests/entries-api/idlharness.window.js b/testing/web-platform/tests/entries-api/idlharness.window.js
new file mode 100644
index 0000000000..32527be514
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/idlharness.window.js
@@ -0,0 +1,15 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+'use strict';
+
+idl_test(
+ ['entries-api'],
+ ['FileAPI', 'html', 'dom'],
+ idl_array => {
+ idl_array.add_objects({
+ File: ['new File([], "example.txt")'],
+ HTMLInputElement: ['document.createElement("input")'],
+ });
+ }
+);
diff --git a/testing/web-platform/tests/entries-api/support.js b/testing/web-platform/tests/entries-api/support.js
new file mode 100644
index 0000000000..1cf3ad95b9
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support.js
@@ -0,0 +1,138 @@
+// ----------------------------------------
+// Test Utilities
+// ----------------------------------------
+
+setup({explicit_timeout: true});
+
+const tests = [];
+window.addEventListener('DOMContentLoaded', e => {
+ const header = document.createElement('h1');
+ header.innerText = document.title;
+ document.body.appendChild(header);
+ const elem = document.createElement('div');
+ elem.style.cssText = 'height: 50px; border: 1px dotted red;';
+ elem.innerHTML = 'Drop or paste the <b>support/upload</b> directory here.</div>';
+ document.body.appendChild(elem);
+ elem.addEventListener('dragover', e => {
+ e.preventDefault();
+ });
+ const onDropOrPaste = dataTransfer => {
+ for (let i = 0; i < dataTransfer.items.length; ++i) {
+ const item = dataTransfer.items[i];
+ if (item.kind !== 'file')
+ continue;
+ const entry = item.webkitGetAsEntry();
+ elem.parentElement.removeChild(elem);
+ tests.forEach(f => f(entry, item));
+ break;
+ }
+ };
+ elem.addEventListener('drop', e => {
+ e.preventDefault();
+ onDropOrPaste(e.dataTransfer);
+ });
+ elem.addEventListener('paste', e => {
+ e.preventDefault();
+ onDropOrPaste(e.clipboardData);
+ });
+});
+
+
+// Registers a test to be run when an entry is dropped. Calls |func|
+// with (test, entry, item); |func| must call `test.done()` when complete.
+function entry_test(func, description) {
+ const test = async_test(description);
+ tests.push(test.step_func((entry, item) => func(test, entry, item)));
+}
+
+// Registers a test to be run when an entry is dropped. Digs the named
+// |file| out of the dropped entry and calls |func| with
+// (test, file_entry); |func| must call `test.done()` when complete.
+function file_entry_test(name, func, description) {
+ return entry_test((t, entry, item) => {
+ getChildEntry(entry, name,
+ t.step_func((entry) => func(t, entry)),
+ t.unreached_func('Did not find expected file: ' + name));
+ }, description);
+}
+
+
+// ----------------------------------------
+// Paths
+// ----------------------------------------
+
+const INVALID_PATHS = [
+ '\x00', 'a-\x00-b',
+ '\\', 'a-\\-b'
+];
+const EMPTY_PATHS = ['', null, undefined];
+const NOT_FOUND_PATHS = [
+ 'nope',
+ '/upload/nope',
+ './nope',
+ 'subdir/../nope',
+ '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
+ '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f',
+];
+
+const DIR_PATHS = [
+ 'subdir',
+ '/upload/subdir',
+ './subdir',
+ 'subdir/.',
+ 'subdir/../subdir',
+ 'subdir/./../subdir',
+ 'subdir/../subdir/.',
+ '//upload/subdir',
+ '/upload//subdir',
+ './/subdir',
+ 'subdir//.',
+];
+const FILE_PATHS = [
+ 'file.txt',
+ '/upload/file.txt',
+ 'subdir/../file.txt',
+ '//upload/file.txt',
+ '/upload//file.txt',
+ 'subdir/./../file.txt',
+];
+
+// ----------------------------------------
+// Helpers
+// ----------------------------------------
+
+// Wrapper for FileSystemDirectoryReader that yields all entries via a
+// Promise.
+
+function getEntriesAsPromise(dirEntry) {
+ return new Promise((resolve, reject) => {
+ const result = [];
+ const reader = dirEntry.createReader();
+ const doBatch = () => {
+ reader.readEntries(entries => {
+ if (entries.length > 0) {
+ entries.forEach(e => result.push(e));
+ doBatch();
+ } else {
+ resolve(result);
+ }
+ }, reject);
+ };
+ doBatch();
+ });
+}
+
+
+// Wrapper for FileSystemDirectoryReader that yields a single entry by
+// name via a callback. Can be used instead of getFile() or
+// getDirectory() since not all implementations support those.
+
+function getChildEntry(dirEntry, name, callback, errback) {
+ getEntriesAsPromise(dirEntry)
+ .then(entries => {
+ const entry = entries.filter(entry => entry.name === name)[0];
+ if (!entry)
+ throw new Error('No such file: ' + name);
+ return entry;
+ }).then(callback, errback);
+}
diff --git a/testing/web-platform/tests/entries-api/support/a/b/c/3.txt b/testing/web-platform/tests/entries-api/support/a/b/c/3.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/a/b/c/3.txt
diff --git a/testing/web-platform/tests/entries-api/support/a/b/c/d/1.txt b/testing/web-platform/tests/entries-api/support/a/b/c/d/1.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/a/b/c/d/1.txt
diff --git a/testing/web-platform/tests/entries-api/support/a/b/c/d/2.txt b/testing/web-platform/tests/entries-api/support/a/b/c/d/2.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/a/b/c/d/2.txt
diff --git a/testing/web-platform/tests/entries-api/support/upload.txt b/testing/web-platform/tests/entries-api/support/upload.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/upload.txt
diff --git a/testing/web-platform/tests/entries-api/support/upload/file.txt b/testing/web-platform/tests/entries-api/support/upload/file.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/upload/file.txt
diff --git a/testing/web-platform/tests/entries-api/support/upload/subdir/1.txt b/testing/web-platform/tests/entries-api/support/upload/subdir/1.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/upload/subdir/1.txt
diff --git a/testing/web-platform/tests/entries-api/support/upload/subdir/2.txt b/testing/web-platform/tests/entries-api/support/upload/subdir/2.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/upload/subdir/2.txt
diff --git a/testing/web-platform/tests/entries-api/support/upload/subdir/3.txt b/testing/web-platform/tests/entries-api/support/upload/subdir/3.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support/upload/subdir/3.txt