Update web-platform-tests to revision 10168e9a5d44efbc6e7d416d1d454eb9c9f1396c

This commit is contained in:
Josh Matthews 2018-01-31 09:13:41 -05:00
parent c88dc51d03
commit 0e1caebaf4
791 changed files with 23381 additions and 5501 deletions

View file

@ -51,3 +51,27 @@
[createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap] [createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL expected: FAIL
[createImageBitmap from a bitmap HTMLImageElement, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a bitmap HTMLImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a vector HTMLImageElement, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a vector HTMLImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a bitmap SVGImageElement, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a bitmap SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a vector SVGImageElement, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a vector SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL

View file

@ -1,5 +1,6 @@
[createImageBitmap-invalid-args.html] [createImageBitmap-invalid-args.html]
type: testharness type: testharness
expected: TIMEOUT
[createImageBitmap with a HTMLImageElement source and sw set to 0 rejects with a RangeError.] [createImageBitmap with a HTMLImageElement source and sw set to 0 rejects with a RangeError.]
expected: FAIL expected: FAIL
@ -118,68 +119,122 @@
expected: FAIL expected: FAIL
[createImageBitmap with a an OffscreenCanvas source and sw set to 0] [createImageBitmap with a an OffscreenCanvas source and sw set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an OffscreenCanvas source and sh set to 0] [createImageBitmap with a an OffscreenCanvas source and sh set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an OffscreenCanvas source and oversized (unallocatable) crop region] [createImageBitmap with a an OffscreenCanvas source and oversized (unallocatable) crop region]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageData source and sw set to 0] [createImageBitmap with a an ImageData source and sw set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageData source and sh set to 0] [createImageBitmap with a an ImageData source and sh set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageData source and oversized (unallocatable) crop region] [createImageBitmap with a an ImageData source and oversized (unallocatable) crop region]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageBitmap source and sw set to 0] [createImageBitmap with a an ImageBitmap source and sw set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageBitmap source and sh set to 0] [createImageBitmap with a an ImageBitmap source and sh set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a an ImageBitmap source and oversized (unallocatable) crop region] [createImageBitmap with a an ImageBitmap source and oversized (unallocatable) crop region]
expected: FAIL expected: NOTRUN
[createImageBitmap with a a Blob source and sw set to 0] [createImageBitmap with a a Blob source and sw set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a a Blob source and sh set to 0] [createImageBitmap with a a Blob source and sh set to 0]
expected: FAIL expected: NOTRUN
[createImageBitmap with a a Blob source and oversized (unallocatable) crop region] [createImageBitmap with a a Blob source and oversized (unallocatable) crop region]
expected: FAIL expected: NOTRUN
[createImageBitmap with undefined image source.] [createImageBitmap with undefined image source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with null image source.] [createImageBitmap with null image source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with empty image source.] [createImageBitmap with empty image source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with empty video source.] [createImageBitmap with empty video source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with an oversized canvas source.] [createImageBitmap with an oversized canvas source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with an invalid OffscreenCanvas source.] [createImageBitmap with an invalid OffscreenCanvas source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with an undecodable blob source.] [createImageBitmap with an undecodable blob source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with a broken image source.] [createImageBitmap with a broken image source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with an available but undecodable image source.] [createImageBitmap with an available but undecodable image source.]
expected: FAIL expected: NOTRUN
[createImageBitmap with a closed ImageBitmap.] [createImageBitmap with a closed ImageBitmap.]
expected: NOTRUN
[createImageBitmap with a a bitmap HTMLImageElement source and sw set to 0]
expected: FAIL expected: FAIL
[createImageBitmap with a a bitmap HTMLImageElement source and sh set to 0]
expected: FAIL
[createImageBitmap with a a bitmap HTMLImageElement source and oversized (unallocatable) crop region]
expected: FAIL
[createImageBitmap with a a vector HTMLImageElement source and sw set to 0]
expected: TIMEOUT
[createImageBitmap with a a vector HTMLImageElement source and sh set to 0]
expected: NOTRUN
[createImageBitmap with a a vector HTMLImageElement source and oversized (unallocatable) crop region]
expected: NOTRUN
[createImageBitmap with a a bitmap SVGImageElement source and sw set to 0]
expected: NOTRUN
[createImageBitmap with a a bitmap SVGImageElement source and sh set to 0]
expected: NOTRUN
[createImageBitmap with a a bitmap SVGImageElement source and oversized (unallocatable) crop region]
expected: NOTRUN
[createImageBitmap with a a vector SVGImageElement source and sw set to 0]
expected: NOTRUN
[createImageBitmap with a a vector SVGImageElement source and sh set to 0]
expected: NOTRUN
[createImageBitmap with a a vector SVGImageElement source and oversized (unallocatable) crop region]
expected: NOTRUN
[createImageBitmap with CanvasRenderingContext2D image source.]
expected: NOTRUN
[createImageBitmap with WebGLRenderingContext image source.]
expected: NOTRUN
[createImageBitmap with Uint8Array image source.]
expected: NOTRUN
[createImageBitmap with ArrayBuffer image source.]
expected: NOTRUN
[createImageBitmap with an available but zero height image source.]
expected: NOTRUN
[createImageBitmap with an available but zero width image source.]
expected: NOTRUN

View file

@ -0,0 +1,16 @@
[createImageBitmap-origin.sub.html]
[cross-origin HTMLImageElement]
expected: FAIL
[cross-origin SVGImageElement]
expected: FAIL
[cross-origin HTMLVideoElement]
expected: FAIL
[unclean HTMLCanvasElement]
expected: FAIL
[unclean ImageBitmap]
expected: FAIL

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
[float-applies-to-008.xht]
type: reftest
expected:
if os == "mac": FAIL

View file

@ -1,3 +0,0 @@
[width-inherit-001.xht]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[abspos-027.xht]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[color-000.xht]
type: reftest
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgb-002.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgb-004.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgb-006.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgb-008.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgba-002.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgba-004.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgba-006.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[rgba-008.html]
expected: FAIL

View file

@ -1,4 +1,3 @@
[floats-028.xht] [adlam-anti-ref.html]
type: reftest
expected: expected:
if os == "mac": FAIL if os == "mac": FAIL

View file

@ -0,0 +1,3 @@
[cypriot-anti-ref.html]
expected:
if os == "mac": FAIL

View file

@ -0,0 +1,25 @@
[perspective-origin-parsing-invalid.html]
[e.style['perspective-origin'\] = "center left 1px" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "center top 2px" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "right 3% center" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "left 4px top" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "right top 5px" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "bottom 6% center" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "bottom 7% left" should not set the property value]
expected: FAIL
[e.style['perspective-origin'\] = "bottom right 8%" should not set the property value]
expected: FAIL

View file

@ -5,3 +5,9 @@
[Serialization should round-trip after setting e.style['translate'\] = "1px 2px 0"] [Serialization should round-trip after setting e.style['translate'\] = "1px 2px 0"]
expected: FAIL expected: FAIL
[e.style['translate'\] = "0" should set the property value]
expected: FAIL
[e.style['translate'\] = "1px 2px 0" should set the property value]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-caption-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-tbody-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-td-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-tfoot-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-th-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-thead-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-transformed-tr-contains-fixed-position.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[text-overflow-024.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[text-overflow-025.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[text-overflow-026.html]
expected: FAIL

View file

@ -0,0 +1,4 @@
[calc-in-font-feature-settings.html]
[calc() in font-feature-settings]
expected: FAIL

View file

@ -0,0 +1,2 @@
[vh_not_refreshing_on_chrome.html]
expected: FAIL

View file

@ -0,0 +1,10 @@
[scrollIntoView-scrollMargin.html]
[scrollIntoView({block: "center", inline: "center"})]
expected: FAIL
[scrollIntoView({block: "start", inline: "start"})]
expected: FAIL
[scrollIntoView({block: "end", inline: "end"})]
expected: FAIL

View file

@ -0,0 +1,10 @@
[scrollIntoView-scrollPadding.html]
[scrollIntoView({block: "center", inline: "center"})]
expected: FAIL
[scrollIntoView({block: "start", inline: "start"})]
expected: FAIL
[scrollIntoView({block: "end", inline: "end"})]
expected: FAIL

View file

@ -3,3 +3,6 @@
[MediaList] [MediaList]
expected: FAIL expected: FAIL
[CSSOM - MediaList interface]
expected: FAIL

View file

@ -566,18 +566,9 @@
[subtest_335] [subtest_335]
expected: FAIL expected: FAIL
[subtest_338]
expected: FAIL
[subtest_340] [subtest_340]
expected: FAIL expected: FAIL
[subtest_346]
expected: FAIL
[subtest_350]
expected: FAIL
[subtest_80] [subtest_80]
expected: FAIL expected: FAIL
@ -764,24 +755,39 @@
[subtest_337] [subtest_337]
expected: FAIL expected: FAIL
[subtest_349]
expected: FAIL
[subtest_353]
expected: FAIL
[subtest_354]
expected: FAIL
[subtest_357]
expected: FAIL
[subtest_358]
expected: FAIL
[subtest_359] [subtest_359]
expected: FAIL expected: FAIL
[subtest_360] [subtest_360]
expected: FAIL expected: FAIL
[subtest_334]
expected: FAIL
[subtest_339]
expected: FAIL
[subtest_342]
expected: FAIL
[subtest_348]
expected: FAIL
[subtest_351]
expected: FAIL
[subtest_352]
expected: FAIL
[subtest_355]
expected: FAIL
[subtest_356]
expected: FAIL
[subtest_361]
expected: FAIL
[subtest_362]
expected: FAIL

View file

@ -0,0 +1,4 @@
[sheet-going-away-001.html]
[Style should be recomputed correctly when the stylesheet it depends on goes away]
expected: FAIL

View file

@ -0,0 +1,2 @@
[Document-createElement-svg.svg]
expected: TIMEOUT

View file

@ -0,0 +1,4 @@
[builtin-coverage.html]
[Untitled]
expected: FAIL

View file

@ -0,0 +1,4 @@
[parser-sets-attributes-and-children.html]
expected:
if os == "mac": CRASH
if os == "linux": TIMEOUT

View file

@ -6,3 +6,6 @@
[Testing empty Response Content-Type header] [Testing empty Response Content-Type header]
expected: FAIL expected: FAIL
[Testing null Response body]
expected: FAIL

View file

@ -0,0 +1,153 @@
[base64.any.worker.html]
[data: URL base64 handling: ""]
expected: FAIL
[data: URL base64 handling: "abcd"]
expected: FAIL
[data: URL base64 handling: " abcd"]
expected: FAIL
[data: URL base64 handling: "abcd "]
expected: FAIL
[data: URL base64 handling: "ab"]
expected: FAIL
[data: URL base64 handling: "abc"]
expected: FAIL
[data: URL base64 handling: "ab="]
expected: FAIL
[data: URL base64 handling: "ab=="]
expected: FAIL
[data: URL base64 handling: "abc="]
expected: FAIL
[data: URL base64 handling: "ab\\tcd"]
expected: FAIL
[data: URL base64 handling: "ab\\ncd"]
expected: FAIL
[data: URL base64 handling: "ab\\fcd"]
expected: FAIL
[data: URL base64 handling: "ab\\rcd"]
expected: FAIL
[data: URL base64 handling: "ab cd"]
expected: FAIL
[data: URL base64 handling: "ab\\t\\n\\f\\r cd"]
expected: FAIL
[data: URL base64 handling: " \\t\\n\\f\\r ab\\t\\n\\f\\r cd\\t\\n\\f\\r "]
expected: FAIL
[data: URL base64 handling: "ab\\t\\n\\f\\r =\\t\\n\\f\\r =\\t\\n\\f\\r "]
expected: FAIL
[data: URL base64 handling: "/A"]
expected: FAIL
[data: URL base64 handling: "//A"]
expected: FAIL
[data: URL base64 handling: "///A"]
expected: FAIL
[data: URL base64 handling: "A/"]
expected: FAIL
[data: URL base64 handling: "AA/"]
expected: FAIL
[data: URL base64 handling: "AAA/"]
expected: FAIL
[data: URL base64 handling: "YQ"]
expected: FAIL
[data: URL base64 handling: "YR"]
expected: FAIL
[base64.any.html]
[data: URL base64 handling: ""]
expected: FAIL
[data: URL base64 handling: "abcd"]
expected: FAIL
[data: URL base64 handling: " abcd"]
expected: FAIL
[data: URL base64 handling: "abcd "]
expected: FAIL
[data: URL base64 handling: "ab"]
expected: FAIL
[data: URL base64 handling: "abc"]
expected: FAIL
[data: URL base64 handling: "ab="]
expected: FAIL
[data: URL base64 handling: "ab=="]
expected: FAIL
[data: URL base64 handling: "abc="]
expected: FAIL
[data: URL base64 handling: "ab\\tcd"]
expected: FAIL
[data: URL base64 handling: "ab\\ncd"]
expected: FAIL
[data: URL base64 handling: "ab\\fcd"]
expected: FAIL
[data: URL base64 handling: "ab\\rcd"]
expected: FAIL
[data: URL base64 handling: "ab cd"]
expected: FAIL
[data: URL base64 handling: "ab\\t\\n\\f\\r cd"]
expected: FAIL
[data: URL base64 handling: " \\t\\n\\f\\r ab\\t\\n\\f\\r cd\\t\\n\\f\\r "]
expected: FAIL
[data: URL base64 handling: "ab\\t\\n\\f\\r =\\t\\n\\f\\r =\\t\\n\\f\\r "]
expected: FAIL
[data: URL base64 handling: "/A"]
expected: FAIL
[data: URL base64 handling: "//A"]
expected: FAIL
[data: URL base64 handling: "///A"]
expected: FAIL
[data: URL base64 handling: "A/"]
expected: FAIL
[data: URL base64 handling: "AA/"]
expected: FAIL
[data: URL base64 handling: "AAA/"]
expected: FAIL
[data: URL base64 handling: "YQ"]
expected: FAIL
[data: URL base64 handling: "YR"]
expected: FAIL

View file

@ -0,0 +1,381 @@
[processing.any.worker.html]
["data://test/,X"]
expected: FAIL
["data:,X"]
expected: FAIL
["data:,"]
expected: FAIL
["data:,X#X"]
expected: FAIL
["data:,%FF"]
expected: FAIL
["data:text/plain,X"]
expected: FAIL
["data:text/plain ,X"]
expected: FAIL
["data:text/plain%20,X"]
expected: FAIL
["data:text/plain\\f,X"]
expected: FAIL
["data:text/plain%0C,X"]
expected: FAIL
["data:text/plain;,X"]
expected: FAIL
["data:;x=x;charset=x,X"]
expected: FAIL
["data:;x=x,X"]
expected: FAIL
["data:text/plain;charset=windows-1252,%C2%B1"]
expected: FAIL
["data:text/plain;Charset=UTF-8,%C2%B1"]
expected: FAIL
["data:image/gif,%C2%B1"]
expected: FAIL
["data:IMAGE/gif,%C2%B1"]
expected: FAIL
["data:IMAGE/gif;hi=x,%C2%B1"]
expected: FAIL
["data:IMAGE/gif;CHARSET=x,%C2%B1"]
expected: FAIL
["data: ,%FF"]
expected: FAIL
["data:%20,%FF"]
expected: FAIL
["data:\\f,%FF"]
expected: FAIL
["data:%1F,%FF"]
expected: FAIL
["data:\\0,%FF"]
expected: FAIL
["data:%00,%FF"]
expected: FAIL
["data:text/html ,X"]
expected: FAIL
["data:text / html,X"]
expected: FAIL
["data:†,X"]
expected: FAIL
["data:†/†,X"]
expected: FAIL
["data:X,X"]
expected: FAIL
["data:image/png,X X"]
expected: FAIL
["data:application/xml,X X"]
expected: FAIL
["data:unknown/unknown,X X"]
expected: FAIL
["data:text/plain;a=\\",\\",X"]
expected: FAIL
["data:text/plain;a=%2C,X"]
expected: FAIL
["data:;base64;base64,WA"]
expected: FAIL
["data:x/x;base64;base64,WA"]
expected: FAIL
["data:x/x;base64;charset=x,WA"]
expected: FAIL
["data:x/x;base64;charset=x;base64,WA"]
expected: FAIL
["data:x/x;base64;base64x,WA"]
expected: FAIL
["data:;base64,W%20A"]
expected: FAIL
["data:;base64,W%0CA"]
expected: FAIL
["data:x;base64x,WA"]
expected: FAIL
["data:x;base64;x,WA"]
expected: FAIL
["data:x;base64=x,WA"]
expected: FAIL
["data:; base64,WA"]
expected: FAIL
["data:; base64,WA"]
expected: FAIL
["data: ;charset=x ; base64,WA"]
expected: FAIL
["data:;base64;,WA"]
expected: FAIL
["data:;base64 ,WA"]
expected: FAIL
["data:;base64 ,WA"]
expected: FAIL
["data:;base 64,WA"]
expected: FAIL
["data:;BASe64,WA"]
expected: FAIL
["data:;%62ase64,WA"]
expected: FAIL
["data:%3Bbase64,WA"]
expected: FAIL
["data:;charset=x,X"]
expected: FAIL
["data:; charset=x,X"]
expected: FAIL
["data:;charset =x,X"]
expected: FAIL
["data:;charset= x,X"]
expected: FAIL
["data:;charset=,X"]
expected: FAIL
["data:;charset,X"]
expected: FAIL
["data:;charset=\\"x\\",X"]
expected: FAIL
["data:;CHARSET=\\"X\\",X"]
expected: FAIL
[processing.any.html]
["data://test/,X"]
expected: FAIL
["data:,X"]
expected: FAIL
["data:,"]
expected: FAIL
["data:,X#X"]
expected: FAIL
["data:,%FF"]
expected: FAIL
["data:text/plain,X"]
expected: FAIL
["data:text/plain ,X"]
expected: FAIL
["data:text/plain%20,X"]
expected: FAIL
["data:text/plain\\f,X"]
expected: FAIL
["data:text/plain%0C,X"]
expected: FAIL
["data:text/plain;,X"]
expected: FAIL
["data:;x=x;charset=x,X"]
expected: FAIL
["data:;x=x,X"]
expected: FAIL
["data:text/plain;charset=windows-1252,%C2%B1"]
expected: FAIL
["data:text/plain;Charset=UTF-8,%C2%B1"]
expected: FAIL
["data:image/gif,%C2%B1"]
expected: FAIL
["data:IMAGE/gif,%C2%B1"]
expected: FAIL
["data:IMAGE/gif;hi=x,%C2%B1"]
expected: FAIL
["data:IMAGE/gif;CHARSET=x,%C2%B1"]
expected: FAIL
["data: ,%FF"]
expected: FAIL
["data:%20,%FF"]
expected: FAIL
["data:\\f,%FF"]
expected: FAIL
["data:%1F,%FF"]
expected: FAIL
["data:\\0,%FF"]
expected: FAIL
["data:%00,%FF"]
expected: FAIL
["data:text/html ,X"]
expected: FAIL
["data:text / html,X"]
expected: FAIL
["data:†,X"]
expected: FAIL
["data:†/†,X"]
expected: FAIL
["data:X,X"]
expected: FAIL
["data:image/png,X X"]
expected: FAIL
["data:application/xml,X X"]
expected: FAIL
["data:unknown/unknown,X X"]
expected: FAIL
["data:text/plain;a=\\",\\",X"]
expected: FAIL
["data:text/plain;a=%2C,X"]
expected: FAIL
["data:;base64;base64,WA"]
expected: FAIL
["data:x/x;base64;base64,WA"]
expected: FAIL
["data:x/x;base64;charset=x,WA"]
expected: FAIL
["data:x/x;base64;charset=x;base64,WA"]
expected: FAIL
["data:x/x;base64;base64x,WA"]
expected: FAIL
["data:;base64,W%20A"]
expected: FAIL
["data:;base64,W%0CA"]
expected: FAIL
["data:x;base64x,WA"]
expected: FAIL
["data:x;base64;x,WA"]
expected: FAIL
["data:x;base64=x,WA"]
expected: FAIL
["data:; base64,WA"]
expected: FAIL
["data:; base64,WA"]
expected: FAIL
["data: ;charset=x ; base64,WA"]
expected: FAIL
["data:;base64;,WA"]
expected: FAIL
["data:;base64 ,WA"]
expected: FAIL
["data:;base64 ,WA"]
expected: FAIL
["data:;base 64,WA"]
expected: FAIL
["data:;BASe64,WA"]
expected: FAIL
["data:;%62ase64,WA"]
expected: FAIL
["data:%3Bbase64,WA"]
expected: FAIL
["data:;charset=x,X"]
expected: FAIL
["data:; charset=x,X"]
expected: FAIL
["data:;charset =x,X"]
expected: FAIL
["data:;charset= x,X"]
expected: FAIL
["data:;charset=,X"]
expected: FAIL
["data:;charset,X"]
expected: FAIL
["data:;charset=\\"x\\",X"]
expected: FAIL
["data:;CHARSET=\\"X\\",X"]
expected: FAIL

View file

@ -0,0 +1,5 @@
[pageload-image-in-popup.html]
expected: ERROR
[The document for a standalone media file should have one child in the body.]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[scroll-to-anchor-name.html]
[Fragment Navigation: scroll to anchor name is lower priority than equal id]
expected: FAIL

View file

@ -13908,3 +13908,6 @@
[HTMLSlotElement interface: calling assignedElements(AssignedNodesOptions) on document.createElement("slot") with too few arguments must throw TypeError] [HTMLSlotElement interface: calling assignedElements(AssignedNodesOptions) on document.createElement("slot") with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[OffscreenCanvas interface: operation getContext(OffscreenRenderingContextId, any)]
expected: FAIL

View file

@ -23,3 +23,6 @@
[location.href : unpaired surrogate codepoint should be replaced with U+FFFD] [location.href : unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL expected: FAIL
[sendBeacon URL: unpaired surrogate codepoint should not make any exceptions.]
expected: FAIL

View file

@ -123,3 +123,6 @@
[video/webm with and without codecs] [video/webm with and without codecs]
expected: FAIL expected: FAIL
[fictional formats and codecs not supported]
expected: FAIL

View file

@ -0,0 +1,4 @@
[inline-async-execorder.html]
[Inline async module script execution order]
expected: FAIL

View file

@ -1,5 +1,6 @@
[span-limits.html] [span-limits.html]
type: testharness type: testharness
expected: TIMEOUT
[colspan of 1001 must be treated as 1000] [colspan of 1001 must be treated as 1000]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[rellist-feature-detection.html]
[Make sure that relList based feature detection is working]
expected: FAIL

View file

@ -1,2 +1,2 @@
local: 1f6a864ab5372fe4f59b1a4c3db7cf8e7a79b06d local: c88dc51d03a81e9e405688ccd2baae75d61ffffd
upstream: 08e864fd23048d707cc42bed8538e644d8dec950 upstream: 9ca21c6c87ccec0ff7fdb0fc896d6e9918f3e331

View file

@ -9,3 +9,6 @@
[PerformanceEntry interface: operation toJSON()] [PerformanceEntry interface: operation toJSON()]
expected: FAIL expected: FAIL
[PerformanceObserver interface: operation takeRecords()]
expected: FAIL

View file

@ -43,14 +43,29 @@ function makeVideo() {
}); });
} }
function makeImage() { function makeMakeHTMLImage(src) {
return new Promise(resolve => { return function() {
var img = new Image(); return new Promise(resolve => {
img.onload = function() { var img = new Image();
resolve(img); img.onload = function() {
}; resolve(img);
img.src = "/images/pattern.png"; };
}); img.src = src;
});
}
}
function makeMakeSVGImage(src) {
return function() {
return new Promise((resolve, reject) => {
var image = document.createElementNS(NAMESPACES.svg, "image");
image.onload = () => resolve(image);
image.onerror = reject;
image.setAttribute("externalResourcesRequired", "true");
image.setAttributeNS(NAMESPACES.xlink, 'xlink:href', src);
document.body.appendChild(image);
});
}
} }
function makeImageData() { function makeImageData() {
@ -100,7 +115,10 @@ function makeBlob() {
var imageSourceTypes = [ var imageSourceTypes = [
{ name: 'an HTMLCanvasElement', factory: makeCanvas }, { name: 'an HTMLCanvasElement', factory: makeCanvas },
{ name: 'an HTMLVideoElement', factory: makeVideo }, { name: 'an HTMLVideoElement', factory: makeVideo },
{ name: 'an HTMLImageElement', factory: makeImage }, { name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.png") },
{ name: 'a vector HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.svg") },
{ name: 'a bitmap SVGImageElement', factory: makeMakeSVGImage("/images/pattern.png") },
{ name: 'a vector SVGImageElement', factory: makeMakeSVGImage("/images/pattern.svg") },
{ name: 'an OffscreenCanvas', factory: makeOffscreenCanvas }, { name: 'an OffscreenCanvas', factory: makeOffscreenCanvas },
{ name: 'an ImageData', factory: makeImageData }, { name: 'an ImageData', factory: makeImageData },
{ name: 'an ImageBitmap', factory: makeImageBitmap }, { name: 'an ImageBitmap', factory: makeImageBitmap },

View file

@ -5,7 +5,8 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/common/canvas-tests.js"></script> <script src="/common/canvas-tests.js"></script>
<script src="/common/media.js"></script> <script src="/common/media.js"></script>
<script src="common.js"></script> <script src="/common/namespaces.js"></script>
<script src="common.sub.js"></script>
<link rel="stylesheet" href="/common/canvas-tests.css"> <link rel="stylesheet" href="/common/canvas-tests.css">
<body> <body>
<script> <script>

View file

@ -2,7 +2,8 @@
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/common/media.js"></script> <script src="/common/media.js"></script>
<script src="common.js"></script> <script src="/common/namespaces.js"></script>
<script src="common.sub.js"></script>
<script> <script>
function makeOversizedCanvas() { function makeOversizedCanvas() {
@ -29,17 +30,18 @@ function makeInvalidBlob() {
} }
function makeBrokenImage() { function makeBrokenImage() {
return new Promise(resolve => { return new Promise((resolve, reject) => {
const image = new Image(); const image = new Image();
image.src = "data:,x"; image.src = "data:,x";
image.onload = reject;
image.onerror = () => resolve(image); image.onerror = () => resolve(image);
}); });
} }
function makeAvailableButBrokenImage() { function makeAvailableButBrokenImage(path) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const image = new Image(); const image = new Image();
image.src = "/images/broken.png"; image.src = path;
image.onload = () => resolve(image); image.onload = () => resolve(image);
image.onerror = reject; image.onerror = reject;
}); });
@ -99,6 +101,26 @@ promise_test( t => {
return promise_rejects(t, new TypeError(), createImageBitmap(null)); return promise_rejects(t, new TypeError(), createImageBitmap(null));
}, "createImageBitmap with null image source."); }, "createImageBitmap with null image source.");
promise_test( t => {
var context = document.createElement("canvas").getContext("2d");
return promise_rejects(t, new TypeError(), createImageBitmap(context));
}, "createImageBitmap with CanvasRenderingContext2D image source.");
promise_test( t => {
var context = document.createElement("canvas").getContext("webgl");
return promise_rejects(t, new TypeError(), createImageBitmap(context));
}, "createImageBitmap with WebGLRenderingContext image source.");
promise_test( t => {
var buffer = new Uint8Array();
return promise_rejects(t, new TypeError(), createImageBitmap(buffer));
}, "createImageBitmap with Uint8Array image source.");
promise_test( t => {
var buffer = new ArrayBuffer(8);
return promise_rejects(t, new TypeError(), createImageBitmap(buffer));
}, "createImageBitmap with ArrayBuffer image source.");
promise_test( t => { promise_test( t => {
return promise_rejects(t, "InvalidStateError", return promise_rejects(t, "InvalidStateError",
createImageBitmap(new Image())); createImageBitmap(new Image()));
@ -138,12 +160,26 @@ promise_test( t => {
}, "createImageBitmap with a broken image source."); }, "createImageBitmap with a broken image source.");
promise_test( t => { promise_test( t => {
return makeAvailableButBrokenImage().then(image => { return makeAvailableButBrokenImage("/images/broken.png").then(image => {
return promise_rejects(t, "InvalidStateError", return promise_rejects(t, "InvalidStateError",
createImageBitmap(image)); createImageBitmap(image));
}); });
}, "createImageBitmap with an available but undecodable image source."); }, "createImageBitmap with an available but undecodable image source.");
promise_test( t => {
return makeAvailableButBrokenImage("/images/red-zeroheight.svg").then(image => {
return promise_rejects(t, "InvalidStateError",
createImageBitmap(image));
});
}, "createImageBitmap with an available but zero height image source.");
promise_test( t => {
return makeAvailableButBrokenImage("/images/red-zerowidth.svg").then(image => {
return promise_rejects(t, "InvalidStateError",
createImageBitmap(image));
});
}, "createImageBitmap with an available but zero width image source.");
promise_test( t => { promise_test( t => {
return makeImageBitmap().then(bitmap => { return makeImageBitmap().then(bitmap => {
bitmap.close() bitmap.close()

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>createImageBitmap: origin-clean flag</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/media.js"></script>
<script src="/common/namespaces.js"></script>
<div id=log></div>
<script>
const crossOriginImageUrl = "http://{{domains[www1]}}:{{ports[http][0]}}/images/red.png";
function assert_origin_unclean(bitmap) {
const context = document.createElement("canvas").getContext("2d");
context.drawImage(bitmap, 0, 0);
assert_throws("SecurityError", () => {
context.getImageData(0, 0, 1, 1);
});
}
function makeImage() {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = reject;
image.src = crossOriginImageUrl;
});
}
const arguments = [
{
name: "cross-origin HTMLImageElement",
factory: makeImage,
},
{
name: "cross-origin SVGImageElement",
factory: () => {
return new Promise((resolve, reject) => {
const image = document.createElementNS(NAMESPACES.svg, "image");
image.onload = () => resolve(image);
image.onerror = reject;
image.setAttribute("externalResourcesRequired", "true");
image.setAttributeNS(NAMESPACES.xlink, 'xlink:href', crossOriginImageUrl);
document.body.appendChild(image);
});
},
},
{
name: "cross-origin HTMLVideoElement",
factory: () => {
return new Promise((resolve, reject) => {
const video = document.createElement("video");
video.oncanplaythrough = () => resolve(video);
video.onerror = reject;
video.src = getVideoURI("http://{{domains[www1]}}:{{ports[http][0]}}/media/movie_300");
});
},
},
{
name: "unclean HTMLCanvasElement",
factory: () => {
return makeImage().then(image => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
return canvas;
});
},
},
{
name: "unclean ImageBitmap",
factory: () => {
return makeImage().then(createImageBitmap);
},
},
];
for (let { name, factory } of arguments) {
promise_test(function() {
return factory().then(createImageBitmap).then(assert_origin_unclean);
}, name);
}
</script>

View file

@ -0,0 +1,27 @@
<!doctype html>
<title>Acid3 numbered tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
var tests = undefined;
function gotMessage(e) {
var m = e.data;
if (tests === undefined && "num_tests" in m) {
tests = [];
for (var i = 0; i < m.num_tests; i++) {
tests.push(async_test("Test " + i));
}
} else if ("result" in m) {
var test = m.test;
var passed = m.result === "pass";
var message = m.message;
tests[test].step(function() {
assert_true(passed, message);
});
tests[test].done();
}
}
window.addEventListener("message", gotMessage, false);
</script>
<iframe src="test.html"></iframe>

View file

@ -3419,6 +3419,7 @@
} }
]; ];
window.parent.postMessage({num_tests: tests.length}, "*");
var log = ''; var log = '';
var delay = 10; var delay = 10;
var score = 0, index = 0, retry = 0, errors = 0; var score = 0, index = 0, retry = 0, errors = 0;
@ -3456,6 +3457,7 @@
} else { } else {
fail("no error message"); fail("no error message");
} }
window.parent.postMessage({test: index, result: "pass"}, "*");
} catch (e) { } catch (e) {
var s; var s;
if (e.message) if (e.message)
@ -3464,6 +3466,7 @@
s = e; s = e;
errors += 1; errors += 1;
log += "Test " + zeroPaddedIndex + " failed: " + s + "\n"; log += "Test " + zeroPaddedIndex + " failed: " + s + "\n";
window.parent.postMessage({test: index, result: "fail", message: s}, "*");
}; };
retry = 0; retry = 0;
index += 1; index += 1;

View file

@ -24,16 +24,25 @@ test(function() {
}, "Verify calling 'navigator.sendBeacon()' with a URL that is not a http(s) scheme throws an exception."); }, "Verify calling 'navigator.sendBeacon()' with a URL that is not a http(s) scheme throws an exception.");
// We'll validate that we can send one beacon that uses our entire Quota and then fail to send one that is just one char. // We'll validate that we can send one beacon that uses our entire Quota and then fail to send one that is just one char.
test(function () { promise_test(async () => {
var destinationURL = "/fetch/api/resources/trickle.py?count=1&ms=1000"; function wait(ms) {
return new Promise(res => step_timeout(res, ms));
var firstSuccess = navigator.sendBeacon(destinationURL, maxPayload); }
assert_true(firstSuccess, "calling 'navigator.sendBeacon()' with our max payload size should succeed."); const url = '/fetch/api/resources/trickle.py?count=1&ms=0';
assert_true(navigator.sendBeacon(url, maxPayload),
"calling 'navigator.sendBeacon()' with our max payload size should succeed.");
// Now we'll send just one character. // Now we'll send just one character.
var secondSuccess = navigator.sendBeacon(destinationURL, "1"); assert_false(navigator.sendBeacon(url, '1'),
assert_false(secondSuccess, "calling 'navigator.sendBeacon()' with just one char should fail while our Quota is used up."); "calling 'navigator.sendBeacon()' with just one char should fail while our Quota is used up.");
}, "Verify calling 'navigator.sendBeacon()' with a small payload fails while Quota is completely utilized."); for (let i = 0; i < 20; ++i) {
await wait(100);
if (navigator.sendBeacon(url, maxPayload)) {
return;
}
}
assert_unreached('The quota should recover after fetching.');
}, "Verify the behavior after the quota is exhausted.");
done(); done();

View file

@ -9,6 +9,19 @@ the API to be loaded as needed.
The Chromium implementation is provided by The Chromium implementation is provided by
`../resources/chromium/web-bluetooth-test.js`. `../resources/chromium/web-bluetooth-test.js`.
The Chromium implementation is not included in stable Chrome builds since it
would add too much to the binary size. On Chromium infrastructure, it is run
using the `content_shell` executable.
In the future, Chromium `src/device/bluetooth` may be refactored into a Mojo
service. At this point, it would be possible to add the necessary testing hooks
into stable Chrome without substantially increasing the binary size, similar to
WebUSB.
These bluetooth tests are upstreamed here because other browsers can reuse them
by implementing the [Web Bluetooth Testing API], even if only on their internal
infrastructure.
[Web Bluetooth Testing API]: https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY/ [Web Bluetooth Testing API]: https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY/
# Generated gen-* files from generator.py # Generated gen-* files from generator.py
@ -45,4 +58,4 @@ Usage:
$ python generate.py $ python generate.py
``` ```
More details documented in `generate.py`. More details documented in `generate.py`.

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Reject with SecurityError if requesting a blocklisted ' +
'service.';
const expected = new DOMException(
'requestDevice() called with a filter containing a blocklisted UUID. ' +
'https://goo.gl/4NeimX',
'SecurityError');
bluetooth_test(() => setUpPreconnectedDevice({
knownServiceUUIDs: ['human_interface_device']
})
.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({
filters: [{services: ['human_interface_device']}]
}),
expected, 'Requesting blocklisted service rejects.')),
test_desc);
</script>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Blocklisted UUID in optionalServices is removed and ' +
'access not granted.';
const expected = new DOMException('Origin is not allowed to access the ' +
'service. Tip: Add the service UUID to \'optionalServices\' in ' +
'requestDevice() options. https://goo.gl/HxfxSQ',
'SecurityError');
let device, fake_peripheral;
bluetooth_test(() => getDiscoveredHealthThermometerDevice({
filters: [{services: ['health_thermometer']}],
optionalServices: ['human_interface_device']
})
.then(_ => ({device, fake_peripheral} = _))
.then(() =>
fake_peripheral.setNextGATTConnectionResponse({code: HCI_SUCCESS}))
.then(() => device.gatt.connect())
.then(() =>
fake_peripheral.setNextGATTDiscoveryResponse({code: HCI_SUCCESS}))
.then(() => Promise.all([
assert_promise_rejects_with_message(
device.gatt.getPrimaryService('human_interface_device'),
expected, 'Blocklisted service not accessible.'),
assert_promise_rejects_with_message(
device.gatt.getPrimaryServices('human_interface_device'),
expected, 'Blocklisted services not accessible.')])),
test_desc);
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A device name between 29 and 248 bytes is valid.';
const DEVICE_NAME = 'a_device_name_that_is_longer_than_29_bytes_but_' +
'shorter_than_248_bytes';
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
.then(() => requestDeviceWithTrustedClick({
filters: [{name: DEVICE_NAME}]
}))
.then(device => assert_equals(device.name, DEVICE_NAME)),
test_desc);
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A filter must restrict the devices in some way.';
const expected = new TypeError();
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: [{}]}),
expected),
test_desc);
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'An empty |filters| member should result in a TypeError';
const expected = new DOMException('Failed to execute \'requestDevice\' on ' +
'\'Bluetooth\': \'filters\' member must be non-empty to find any devices.',
new TypeError());
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: []}),
expected),
test_desc);
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'requestDevice with empty namePrefix. ' +
'Should reject with TypeError.';
const expected = new TypeError();
const test_specs = [{
filters: [{ namePrefix: ''}]
}, {
filters: [{ namePrefix: '', name: 'Name'}]
}, {
filters: [{ namePrefix: '', services: ['heart_rate']}]
}, {
filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}]
}, {
filters: [{ namePrefix: ''}],
optionalServices: ['heart_rate']
}, {
filters: [{ namePrefix: '', name: 'Name'}],
optionalServices: ['heart_rate']
}, {
filters: [{ namePrefix: '', services: ['heart_rate']}],
optionalServices: ['heart_rate']
}, {
filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}],
optionalServices: ['heart_rate']
}];
bluetooth_test(() => {
let test_promises = Promise.resolve();
test_specs.forEach(args => {
test_promises = test_promises
.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(args),
expected));
});
return test_promises;
}, test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Services member must contain at least one service.';
const expected = new TypeError();
bluetooth_test(() => {
let test_promises = Promise.resolve();
generateRequestDeviceArgsWithServices([]).forEach(args => {
test_promises = test_promises.then(() =>
assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(args),
expected,
'Services member must contain at least one service'))
});
return test_promises;
}, test_desc);
</script>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = "RequestDeviceOptions should have exactly one of " +
"'filters' or 'acceptAllDevices:true'. Reject with TypeError if not.";
const expected = new DOMException(
"Failed to execute 'requestDevice' on 'Bluetooth': " +
"Either 'filters' should be present or " +
"'acceptAllDevices' should be true, but not both.",
new TypeError());
const test_specs = [
{},
{optionalServices: ['heart_rate']},
{filters: [], acceptAllDevices: true},
{filters: [], acceptAllDevices: true, optionalServices: ['heart_rate']}
];
bluetooth_test(() => {
let test_promises = Promise.resolve();
test_specs.forEach(args => {
test_promises = test_promises
.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(args),
expected))
});
return test_promises;
}, test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Unicode string with utf8 representation longer than 248 ' +
'bytes in \'name\' must throw TypeError.';
const expected = new DOMException(
"Failed to execute 'requestDevice' on 'Bluetooth': " +
"A device name can't be longer than 248 bytes.",
new TypeError());
// \u2764's UTF-8 respresentation is 3 bytes long.
// 83 chars * 3 bytes/char = 249 bytes
const unicode_name = '\u2764'.repeat(83);
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: [{name: unicode_name}]}),
expected),
test_desc);
</script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A device name longer than 248 must reject.';
const expected = new DOMException(
"Failed to execute 'requestDevice' on 'Bluetooth': A device " +
"name can't be longer than 248 bytes.",
new TypeError());
const name_too_long = 'a'.repeat(249);
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: [{name: name_too_long}]}),
expected,
'Device name longer than 248'),
test_desc);
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Unicode string with utf8 representation longer than 248 ' +
'bytes in \'namePrefix\' must throw NotFoundError.';
const expected = new DOMException(
"Failed to execute 'requestDevice' on 'Bluetooth': " +
"A device name can't be longer than 248 bytes.",
new TypeError());
// \u2764's UTF-8 respresentation is 3 bytes long.
// 83 chars * 3 bytes/char = 249 bytes
const unicode_name = '\u2764'.repeat(83);
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: [{namePrefix: unicode_name}]}),
expected),
test_desc);
</script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A device name prefix longer than 248 must reject.';
const expected = new DOMException(
"Failed to execute 'requestDevice' on 'Bluetooth': A device " +
"name can't be longer than 248 bytes.",
new TypeError());
const name_too_long = 'a'.repeat(249);
bluetooth_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({filters: [{namePrefix: name_too_long}]}),
expected,
'Device name longer than 248'),
test_desc);
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A unicode device name of 248 bytes is valid.';
// \u00A1's UTF-8 respresentation is 2 bytes long.
// 124 chars * 2 bytes/char = 248 bytes
const DEVICE_NAME = '\u00A1'.repeat(124);
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
.then(() => requestDeviceWithTrustedClick({ filters: [{name: DEVICE_NAME}]}))
.then(device => assert_equals(device.name, DEVICE_NAME)),
test_desc);
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A device name of 248 bytes is valid.';
const DEVICE_NAME = 'a'.repeat(248);
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
.then(() => requestDeviceWithTrustedClick({ filters: [{name: DEVICE_NAME}]}))
.then(device => assert_equals(device.name, DEVICE_NAME)),
test_desc);
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A unicode device namePrefix of 248 bytes is valid.';
// \u00A1's UTF-8 respresentation is 2 bytes long.
// 124 chars * 2 bytes/char = 248 bytes
const DEVICE_NAME = '\u00A1'.repeat(124);
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
.then(() => requestDeviceWithTrustedClick({
filters: [{namePrefix: DEVICE_NAME}]
}))
.then(device => assert_equals(device.name, DEVICE_NAME)),
test_desc);
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A device namePrefix of 248 bytes is valid.';
const DEVICE_NAME = 'a'.repeat(248);
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
.then(() => requestDeviceWithTrustedClick({
filters: [{namePrefix: DEVICE_NAME}]
}))
.then(device => assert_equals(device.name, DEVICE_NAME)),
test_desc);
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharness-helpers.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'requestDevice() requires an argument.';
const expected = new TypeError();
promise_test(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(),
expected),
test_desc);
</script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A name containing unicode characters whose utf8 length ' +
'is less than 30 must not throw an error.';
// \u2764's UTF-8 representation is 3 bytes long.
// 9 chars * 3 bytes/char = 27 bytes
const valid_unicode_name = '\u2764'.repeat(9);
bluetooth_test(() => setUpPreconnectedDevice({name: valid_unicode_name})
.then(() => requestDeviceWithTrustedClick({
filters: [{name: valid_unicode_name}]
}))
.then(device => assert_equals(device.name, valid_unicode_name)),
test_desc);
</script>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'A namePrefix containing unicode characters whose utf8 ' +
'length is less than 30 must not throw an error.';
// \u2764's UTF-8 representation is 3 bytes long.
// 9 chars * 3 bytes/char = 27 bytes
const valid_unicode_name = '\u2764'.repeat(9);
bluetooth_test(() => setUpPreconnectedDevice({name: valid_unicode_name})
.then(() => requestDeviceWithTrustedClick({
filters: [{namePrefix: valid_unicode_name}]
}))
.then(device => assert_equals(device.name, valid_unicode_name)),
test_desc);
</script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Invalid optional service must reject the promise.';
const expected = new TypeError();
const test_specs = [{
optionalServices: ['wrong_service'],
filters: [{services: ['heart_rate']}]
}, {
optionalServices: ['wrong_service'],
filters: [{ services: ['heart_rate'], name: 'Name'}]
}, {
optionalServices: ['wrong_service'],
filters: [{ services: ['heart_rate'], namePrefix: 'Pre'}]
}, {
optionalServices: ['wrong_service'],
filters: [{ services: ['heart_rate'], name: 'Name', namePrefix: 'Pre'}]
}, {
optionalServices: ['wrong_service'],
filters: [{ name: 'Name'}]
}, {
optionalServices: ['wrong_service'],
filters: [{ name: 'Name', namePrefix: 'Pre'}]
}, {
optionalServices: ['wrong_service'],
filters: [{ namePrefix: 'Pre'}]
}];
bluetooth_test(() => {
let test_promises = Promise.resolve();
test_specs.forEach(args => {
test_promises =
test_promises.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(args),
expected));
});
return test_promises;
}, test_desc);
</script>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Invalid service must reject the promise.';
const expected = new TypeError();
bluetooth_test(() => {
let test_promises = Promise.resolve();
generateRequestDeviceArgsWithServices(['wrong_service']).forEach(args => {
test_promises = test_promises.then(() =>
assert_promise_rejects_with_message(
requestDeviceWithTrustedClick(args),
expected));
});
return test_promises;
}, test_desc);
</script>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Consumes a user gesture.';
const expected = new DOMException(
'Must be handling a user gesture to show a permission request.',
'SecurityError');
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
.then(() => callWithTrustedClick(() => {
let first = navigator.bluetooth.requestDevice({
filters: [{services: ['heart_rate']}]});
let second = navigator.bluetooth.requestDevice({
filters: [{services: ['heart_rate']}]});
return Promise.all([
first.then(device => assert_equals(
device.constructor.name, 'BluetoothDevice')),
assert_promise_rejects_with_message(second,
expected, 'A request should consume a user gesture')
]);
})), test_desc);
</script>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Discover a device using alias, name, or UUID.';
bluetooth_test(() => getHealthThermometerDevice()
// Chrome will always close the previous chooser in the process of handling
// a user gesture for the next request, so these need to be done
// sequentially.
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [health_thermometer.alias]}]
}))
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice'))
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [health_thermometer.name]}]
}))
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice'))
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [health_thermometer.uuid]}]
}))
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice')),
test_desc);
</script>

View file

@ -0,0 +1,67 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Matches a filter if all present members match.';
let matching_services = [health_thermometer.uuid];
let matching_name = 'Health Thermometer';
let matching_namePrefix = 'Health';
let test_specs = [{
filters: [{
services: matching_services,
}]
}, {
filters: [{
services: matching_services,
name: matching_name,
}]
}, {
filters: [{
services: matching_services,
namePrefix: matching_namePrefix
}]
}, {
filters: [{
name: matching_name,
}],
optionalServices: matching_services
}, {
filters: [{
name: matching_name,
namePrefix: matching_namePrefix
}],
optionalServices: matching_services
}, {
filters: [{
namePrefix: matching_namePrefix
}],
optionalServices: matching_services
}, {
filters: [{
services: matching_services,
name: matching_name,
namePrefix: matching_namePrefix
}]
}];
bluetooth_test(() => setUpHealthThermometerDevice()
.then(() => {
let test_promises = Promise.resolve();
test_specs.forEach(args => {
test_promises = test_promises
.then(() => requestDeviceWithTrustedClick(args))
.then(device => {
// We always have access to the services in matching_services
// because we include them in a filter or in optionalServices.
assert_equals(device.name, matching_name);
assert_true(device.name.startsWith(matching_namePrefix));
});
});
return test_promises;
}), test_desc);
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Reject with NotFoundError if Bluetooth is not supported.';
const expected = new DOMException('Bluetooth Low Energy not available.',
'NotFoundError');
bluetooth_test(() => navigator.bluetooth.test.setLESupported(false)
.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({acceptAllDevices: true}),
expected, 'Bluetooth Low Energy is not supported.')),
test_desc);
</script>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'An empty name device can be obtained by empty name filter.'
bluetooth_test(() => setUpPreconnectedDevice({name: ''})
.then(() => requestDeviceWithTrustedClick({filters: [{name: ''}]}))
.then(device => assert_equals(device.name, '')),
test_desc);
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Requires a user gesture.';
const expected = new DOMException(
'Must be handling a user gesture to show a permission request.',
'SecurityError');
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
.then(() => assert_promise_rejects_with_message(
navigator.bluetooth.requestDevice({filters:[{services:['heart_rate']}]}),
expected, 'User gesture is required')),
test_desc);
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Reject with NotFoundError if there is no BT radio present.';
const expected = new DOMException('Bluetooth adapter not available.',
'NotFoundError');
bluetooth_test(() => navigator.bluetooth.test.simulateCentral({state: 'absent'})
.then(() => assert_promise_rejects_with_message(
requestDeviceWithTrustedClick({
filters: [{services: ['generic_access']}]
}),
expected, 'Bluetooth adapter is not present.')),
test_desc);
</script>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Concurrent requestDevice calls in iframes work.';
const iframes = [];
for (let i = 0; i < 5; i++) {
iframes.push(document.createElement('iframe'));
}
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
// 1. Load the iframes.
.then(() => {
let promises = [];
for (let iframe of iframes) {
iframe.src = '/bluetooth/resources/health-thermometer-iframe.html';
document.body.appendChild(iframe);
promises.push(new Promise(resolve =>
iframe.addEventListener('load', resolve)));
}
return Promise.all(promises);
})
// 2. Request the device from the iframes.
.then(() => new Promise(async (resolve) => {
let numMessages = 0;
window.onmessage = messageEvent => {
assert_equals(messageEvent.data, 'Success');
if (++numMessages === iframes.length) {
resolve();
}
}
for (let iframe of iframes) {
await callWithTrustedClick(() => iframe.contentWindow.postMessage({
type: 'RequestDevice'
}, '*'));
}
})), test_desc);
</script>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<body>
<script>
'use strict';
const test_desc = 'Request device from a unique origin. ' +
'Should reject with SecurityError.';
const expected = 'SecurityError: requestDevice() called from cross-origin ' +
'iframe.';
let iframe = document.createElement('iframe');
bluetooth_test(() => getHealthThermometerDevice()
// 1. Load the iframe.
.then(() => new Promise(resolve => {
iframe.sandbox.add('allow-scripts');
iframe.src = '/bluetooth/resources/health-thermometer-iframe.html';
document.body.appendChild(iframe);
iframe.addEventListener('load', resolve);
}))
// 2. Request the device from the iframe.
.then(() => new Promise(resolve => {
callWithTrustedClick(() => {
iframe.contentWindow.postMessage({
type: 'RequestDevice'
}, '*');
});
window.onmessage = messageEvent => {
assert_equals(messageEvent.data, expected);
resolve();
}
})), test_desc);
</script>
</body>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Returned device should always be the same.';
let devices = [];
let push = device => devices.push(device);
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [heart_rate.alias]}]
}))
.then(push)
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [heart_rate.name]}]
}))
.then(push)
.then(() => requestDeviceWithTrustedClick({
filters: [{services: [heart_rate.uuid]}]
}))
.then(push)
.then(() => {
assert_equals(devices[0], devices[1]);
assert_equals(devices[1], devices[2]);
}), test_desc);
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
const test_desc = 'Simple filter selects matching device.';
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
.then(() => requestDeviceWithTrustedClick({
filters: [{services: ['health_thermometer']}]
}))
.then(device => assert_equals(device.name, 'Health Thermometer')),
test_desc);
</script>

View file

@ -218,22 +218,36 @@ var gatt_errors_tests = [{
'NotSupportedError') 'NotSupportedError')
}]; }];
function callWithTrustedClick(callback) { // Waits until the document has finished loading.
function waitForDocumentReady() {
return new Promise(resolve => { return new Promise(resolve => {
let button = document.createElement('button'); if (document.readyState === 'complete') {
button.textContent = 'click to continue test'; resolve();
button.style.display = 'block'; }
button.style.fontSize = '20px';
button.style.padding = '10px'; window.addEventListener('load', () => {
button.onclick = () => { resolve();
document.body.removeChild(button); }, {once: true});
resolve(callback());
};
document.body.appendChild(button);
test_driver.click(button);
}); });
} }
function callWithTrustedClick(callback) {
return waitForDocumentReady()
.then(() => new Promise(resolve => {
let button = document.createElement('button');
button.textContent = 'click to continue test';
button.style.display = 'block';
button.style.fontSize = '20px';
button.style.padding = '10px';
button.onclick = () => {
document.body.removeChild(button);
resolve(callback());
};
document.body.appendChild(button);
test_driver.click(button);
}));
}
// Calls requestDevice() in a context that's 'allowed to show a popup'. // Calls requestDevice() in a context that's 'allowed to show a popup'.
function requestDeviceWithTrustedClick() { function requestDeviceWithTrustedClick() {
let args = arguments; let args = arguments;

View file

@ -1,17 +1,31 @@
<!DOCTYPE html> <!DOCTYPE html>
<script> <script>
let device; let device, gatt;
function requestDeviceWithOptionsAndConnect(options) { function requestDeviceWithOptionsAndConnect(options) {
return navigator.bluetooth.requestDevice(options) return navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect()); .then(device => device.gatt.connect());
} }
window.onmessage = messageEvent => { window.addEventListener('message', (messageEvent) => {
switch (messageEvent.data.type) { switch (messageEvent.data.type) {
case 'RequestDevice':
navigator.bluetooth.requestDevice({
filters: [{services: ['generic_access']}]
})
.then(device => {
if (device.constructor.name === 'BluetoothDevice') {
parent.postMessage('Success', '*');
} else {
parent.postMessage(
`FAIL: requestDevice in iframe returned ${device.name}`, '*');
}}).catch(err => parent.postMessage(`${err.name}: ${err.message}`,
'*'));
break;
case 'RequestAndConnect': case 'RequestAndConnect':
requestDeviceWithOptionsAndConnect(messageEvent.data.options) requestDeviceWithOptionsAndConnect(messageEvent.data.options)
.then(gatt => { .then(_ => {
gatt = _;
device = gatt.device; device = gatt.device;
parent.postMessage('Connected', '*'); parent.postMessage('Connected', '*');
}).catch(err => { }).catch(err => {
@ -26,9 +40,18 @@ window.onmessage = messageEvent => {
parent.postMessage(`FAIL: ${err}`, '*'); parent.postMessage(`FAIL: ${err}`, '*');
}); });
break; break;
case 'GetService':
if (typeof gatt === 'undefined') {
parent.postMessage('FAIL: no GATT server', '*');
break;
}
gatt.getPrimaryService(messageEvent.data.options)
.then(() => parent.postMessage('ServiceReceived', '*'))
.catch(err => parent.postMessage(`FAIL: ${err}`, '*'));
break;
default: default:
parent.postMessage(`FAIL: Bad message type: ${messageEvent.data.type}`, parent.postMessage(`FAIL: Bad message type: ${messageEvent.data.type}`,
'*'); '*');
} }
}; });
</script> </script>

View file

@ -0,0 +1,19 @@
'use strict';
const test_desc = 'Serial Number String characteristic is blocklisted. ' +
'Should reject with SecurityError.';
const expected = new DOMException(
'getCharacteristic(s) called with blocklisted UUID. https://goo.gl/4NeimX',
'SecurityError');
bluetooth_test(() => getHIDDevice({
filters: [{services: ['device_information']}]
})
.then(({device}) => device.gatt.getPrimaryService('device_information'))
.then(service => assert_promise_rejects_with_message(
service.CALLS([
getCharacteristic('serial_number_string')|
getCharacteristics('serial_number_string')[UUID]
]),
expected,
'Serial Number String characteristic is blocklisted.')),
test_desc);

View file

@ -0,0 +1,15 @@
'use strict';
const test_desc = 'Request for absent characteristics with UUID. ' +
'Reject with NotFoundError.';
bluetooth_test(() => getEmptyHealthThermometerService()
.then(({service}) => assert_promise_rejects_with_message(
service.CALLS([
getCharacteristic('battery_level')|
getCharacteristics('battery_level')[UUID]
]),
new DOMException(
`No Characteristics matching UUID ${battery_level.uuid} found ` +
`in Service with UUID ${health_thermometer.uuid}.`,
'NotFoundError'))),
test_desc);

View file

@ -0,0 +1,24 @@
'use strict';
const test_desc = 'Garbage Collection ran during FUNCTION_NAME ' +
'call that fails. Should not crash';
const expected = new DOMException(
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
'(Re)connect first with `device.gatt.connect`.',
'NetworkError');
let promise;
bluetooth_test(() => getHealthThermometerService()
.then(({service}) => {
promise = assert_promise_rejects_with_message(
service.CALLS([
getCharacteristic('measurement_interval')|
getCharacteristics()|
getCharacteristics('measurement_interval')[UUID]
]), expected);
// Disconnect called to clear attributeInstanceMap and allow the object to
// get garbage collected.
service.device.gatt.disconnect();
})
.then(runGarbageCollection)
.then(() => promise),
test_desc);

View file

@ -0,0 +1,24 @@
'use strict';
const test_desc = 'Calls to FUNCTION_NAME should return the same object.';
bluetooth_test(() => getHealthThermometerService()
.then(({service}) => Promise.all([
service.CALLS([
getCharacteristic('measurement_interval')|
getCharacteristics()|
getCharacteristics('measurement_interval')[UUID]]),
service.PREVIOUS_CALL]))
.then(([characteristics_first_call, characteristics_second_call]) => {
// Convert to arrays if necessary.
characteristics_first_call = [].concat(characteristics_first_call);
characteristics_second_call = [].concat(characteristics_second_call);
let first_call_set = new Set(characteristics_first_call);
assert_equals(characteristics_first_call.length, first_call_set.size);
let second_call_set = new Set(characteristics_second_call);
assert_equals(characteristics_second_call.length, second_call_set.size);
characteristics_first_call.forEach(characteristic => {
assert_true(second_call_set.has(characteristic));
});
}), test_desc);

Some files were not shown because too many files have changed in this diff Show more