Update web-platform-tests to revision a49081e46a18e439defbd77d18cc5e261d68b215

This commit is contained in:
WPT Sync Bot 2020-05-12 08:18:49 +00:00
parent aa9f16ce45
commit fb0507d174
69 changed files with 1412 additions and 698 deletions

View file

@ -0,0 +1,2 @@
[border-top-applies-to-009.xht]
expected: CRASH

View file

@ -0,0 +1,4 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -2,6 +2,3 @@
[Hit test intersecting scaled box] [Hit test intersecting scaled box]
expected: FAIL expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -1,16 +1,10 @@
[outline-width-interpolation.html] [outline-width-interpolation.html]
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (1.5) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]] [Web Animations: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (1.5) should be [15px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (1.5) should be [15px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (0.3) should be [13px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]] [CSS Transitions: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
@ -23,27 +17,15 @@
[Web Animations: property <outline-width> from neutral to [20px\] at (0) should be [10px\]] [Web Animations: property <outline-width> from neutral to [20px\] at (0) should be [10px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (0) should be [0px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]] [CSS Transitions: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (-0.3) should be [33px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (-0.3) should be [33px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (1) should be [10px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
@ -65,36 +47,18 @@
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (0) should be [30px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]] [Web Animations: property <outline-width> from [initial\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (0.6) should be [16px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (0.3) should be [8px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (0.3) should be [13px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (1) should be [20px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]]
expected: FAIL expected: FAIL
@ -110,33 +74,21 @@
[Web Animations: property <outline-width> from neutral to [20px\] at (1) should be [20px\]] [Web Animations: property <outline-width> from neutral to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (-0.3) should be [33px\]]
expected: FAIL
[Web Animations: property <outline-width> from [0px\] to [10px\] at (0) should be [0px\]] [Web Animations: property <outline-width> from [0px\] to [10px\] at (0) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (0.6) should be [16px\]]
expected: FAIL
[Web Animations: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]] [Web Animations: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
@ -149,12 +101,6 @@
[Web Animations: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (-0.3) should be [0px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (1) should be [20px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [20px\] at (0.3) should be [8px\]] [Web Animations: property <outline-width> from [initial\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
@ -170,57 +116,33 @@
[CSS Animations: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]] [CSS Animations: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (0.6) should be [6px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (0) should be [5px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]] [CSS Transitions with transition: all: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (-0.3) should be [2px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0) should be [30px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0) should be [30px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (-0.3) should be [33px\]]
expected: FAIL
[CSS Animations: property <outline-width> from neutral to [20px\] at (1.5) should be [25px\]] [CSS Animations: property <outline-width> from neutral to [20px\] at (1.5) should be [25px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [thick\] to [15px\] at (0) should be [5px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (0) should be [5px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (1) should be [20px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (0) should be [0px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]] [CSS Transitions: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0) should be [3px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0) should be [3px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [0px\] to [10px\] at (1) should be [10px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [20px\] at (1.5) should be [28px\]] [CSS Animations: property <outline-width> from [initial\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
@ -233,57 +155,24 @@
[Web Animations: property <outline-width> from [unset\] to [20px\] at (1) should be [20px\]] [Web Animations: property <outline-width> from [unset\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (1) should be [20px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (1.5) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]] [CSS Animations: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (-0.3) should be [2px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (0.6) should be [24px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (1.5) should be [28px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (0.3) should be [8px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]] [CSS Animations: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]] [CSS Animations: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [thick\] to [15px\] at (1.5) should be [20px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (1.5) should be [25px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]] [CSS Animations: property <outline-width> from [thick\] to [15px\] at (-2) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (0) should be [10px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0) should be [3px\]]
expected: FAIL expected: FAIL
@ -293,27 +182,18 @@
[CSS Animations: property <outline-width> from [0px\] to [10px\] at (0.3) should be [3px\]] [CSS Animations: property <outline-width> from [0px\] to [10px\] at (0.3) should be [3px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (0) should be [30px\]]
expected: FAIL
[Web Animations: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]] [Web Animations: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]] [Web Animations: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]] [CSS Animations: property <outline-width> from [thick\] to [15px\] at (1) should be [15px\]]
expected: FAIL expected: FAIL
@ -329,33 +209,18 @@
[Web Animations: property <outline-width> from [thick\] to [15px\] at (-0.3) should be [2px\]] [Web Animations: property <outline-width> from [thick\] to [15px\] at (-0.3) should be [2px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (0.6) should be [6px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]] [CSS Animations: property <outline-width> from [initial\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from [0px\] to [10px\] at (0.3) should be [3px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [thick\] to [15px\] at (0) should be [5px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]] [CSS Animations: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[Web Animations: property <outline-width> from neutral to [20px\] at (0.3) should be [13px\]] [Web Animations: property <outline-width> from neutral to [20px\] at (0.3) should be [13px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (1) should be [20px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (1.5) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [20px\] at (0) should be [3px\]] [Web Animations: property <outline-width> from [initial\] to [20px\] at (0) should be [3px\]]
expected: FAIL expected: FAIL
@ -380,9 +245,6 @@
[CSS Animations: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]] [CSS Animations: property <outline-width> from [thick\] to [15px\] at (0.6) should be [11px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (0.3) should be [3px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0.6) should be [13px\]]
expected: FAIL expected: FAIL
@ -392,9 +254,6 @@
[CSS Animations: property <outline-width> from [inherit\] to [20px\] at (1) should be [20px\]] [CSS Animations: property <outline-width> from [inherit\] to [20px\] at (1) should be [20px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (1.5) should be [25px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0.3) should be [8px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
@ -413,18 +272,9 @@
[CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]] [CSS Transitions with transition: all: property <outline-width> from [initial\] to [20px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [0px\] to [10px\] at (1) should be [10px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]] [CSS Transitions with transition: all: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from neutral to [20px\] at (0) should be [10px\]]
expected: FAIL
[CSS Transitions with transition: all: property <outline-width> from [inherit\] to [20px\] at (0.3) should be [27px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [0px\] to [10px\] at (-0.3) should be [0px\]] [CSS Animations: property <outline-width> from [0px\] to [10px\] at (-0.3) should be [0px\]]
expected: FAIL expected: FAIL
@ -434,12 +284,78 @@
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (0.3) should be [8px\]]
expected: FAIL expected: FAIL
[CSS Transitions: property <outline-width> from neutral to [20px\] at (-0.3) should be [7px\]]
expected: FAIL
[CSS Animations: property <outline-width> from neutral to [20px\] at (0) should be [10px\]]
expected: FAIL
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -315,12 +315,21 @@
[<iframe>: separate response Content-Type: text/html;x=" text/plain] [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain] [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk] [<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL

View file

@ -59,9 +59,6 @@
[separate text/javascript;charset=windows-1252 error text/javascript] [separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL expected: FAIL
[separate text/javascript; charset=windows-1252 text/javascript] [separate text/javascript error]
expected: FAIL
[separate text/javascript;charset=windows-1252 text/javascript]
expected: FAIL expected: FAIL

View file

@ -8,6 +8,6 @@
[X-Content-Type-Options%3A%20nosniff%0C] [X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_2.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_5.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -155807,6 +155807,19 @@
{} {}
] ]
], ],
"scrollbar-empty-001.html": [
"7910f4de950f70e0bd5ba3afcad8596876fdeaef",
[
null,
[
[
"/css/reference/blank.html",
"=="
]
],
{}
]
],
"text-overflow-ellipsis-001.html": [ "text-overflow-ellipsis-001.html": [
"41c11d581e982c7de2d51d38b18decd99e8a60b3", "41c11d581e982c7de2d51d38b18decd99e8a60b3",
[ [
@ -157854,6 +157867,32 @@
{} {}
] ]
], ],
"position-absolute-dynamic-relayout-003.html": [
"8b7556b1f339f6e8db00c17d8f9382b3a37a1658",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-absolute-dynamic-static-position-flex.html": [
"37e6fed3515fa56031fea43aa141cedea0ace117",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-absolute-dynamic-static-position-floats-001.html": [ "position-absolute-dynamic-static-position-floats-001.html": [
"a63df41089e7e75d33ee1f46d458e97c8ebf0fb0", "a63df41089e7e75d33ee1f46d458e97c8ebf0fb0",
[ [
@ -160634,7 +160673,7 @@
] ]
], ],
"ruby-reflow-001-opaqueruby.html": [ "ruby-reflow-001-opaqueruby.html": [
"fe4a80423839f6167fa0e42315b6b814cc839b92", "77feb2e6b8dcdd514114dbec9867529e3bda0323",
[ [
null, null,
[ [
@ -160647,7 +160686,7 @@
] ]
], ],
"ruby-reflow-001-transparentruby.html": [ "ruby-reflow-001-transparentruby.html": [
"3e7112c4d61397e74cd1d75519292f3ecca5e9ee", "008c5250bc364d4a9e15643ce38dc4d18eb7a145",
[ [
null, null,
[ [
@ -160673,7 +160712,7 @@
] ]
], ],
"ruby-whitespace-001.html": [ "ruby-whitespace-001.html": [
"9df61585700777911c19e8336beed37827ce78d4", "9072a8e6841925a5023730ad48b5a2f074b1d0dd",
[ [
null, null,
[ [
@ -160686,7 +160725,7 @@
] ]
], ],
"ruby-whitespace-002.html": [ "ruby-whitespace-002.html": [
"bc84919a123c0554d9a6f80bea7d78341eb6cafe", "98ed78913375ad36d2422ca231cb880a07032741",
[ [
null, null,
[ [
@ -300245,11 +300284,11 @@
[] []
], ],
"ruby-whitespace-001-ref.html": [ "ruby-whitespace-001-ref.html": [
"d24e207f8676d010cdfef2ddac1412833944faaf", "04fa59e6ba038e03a13c8101fcbb6ea39561eed8",
[] []
], ],
"ruby-whitespace-002-ref.html": [ "ruby-whitespace-002-ref.html": [
"8aade20051630ee89d258916b1029a71d91ce0fb", "2b22891738cb1a776e411857b33a7a993c120363",
[] []
], ],
"support": { "support": {
@ -323008,7 +323047,7 @@
[] []
], ],
"cache-storage-reporting.js": [ "cache-storage-reporting.js": [
"af36ccf9d3df852f75af46339e7df6bff23a5402", "86dff9c8459003b7ceeb664ebbac920518505db3",
[] []
], ],
"coep-frame.html": [ "coep-frame.html": [
@ -323079,6 +323118,10 @@
"b7c8b304178b4f4aa213703d6870e84267acba6c", "b7c8b304178b4f4aa213703d6870e84267acba6c",
[] []
], ],
"reporting-worker.js": [
"0f8a2ce4c87da7c0721b3a3d18af0d231fbacda2",
[]
],
"require-corp-sw-import-scripts.js": [ "require-corp-sw-import-scripts.js": [
"e652c5bf303074d7c396f53146bb8af6c3f35644", "e652c5bf303074d7c396f53146bb8af6c3f35644",
[] []
@ -333329,7 +333372,7 @@
] ]
}, },
"lint.ignore": [ "lint.ignore": [
"acdeddbff3935e919bc582bdbdb1af1d6693f26d", "49f88ddc7b339434e071522958fcc2a6aec5d237",
[] []
], ],
"loading": { "loading": {
@ -342907,7 +342950,7 @@
], ],
"tasks": { "tasks": {
"test.yml": [ "test.yml": [
"6e22cc57081ad222c5fd6df7f3783da8ed44d72d", "318437a80ec3240721a17cc6253f241109038b64",
[] []
] ]
}, },
@ -348487,11 +348530,11 @@
[] []
], ],
"browser.py": [ "browser.py": [
"8b1b55f607f961c038ad5fea0afd4ef6a040880f", "366dc781d90ee21b820b9334c69ede2c451cb4b8",
[] []
], ],
"commands.json": [ "commands.json": [
"60fe1621af0decd0faa434f26dcba995154173e7", "a47ab40d72847d5f536e0ac2e02eb3fe0fea233a",
[] []
], ],
"create.py": [ "create.py": [
@ -348649,7 +348692,7 @@
[] []
], ],
"requirements_firefox.txt": [ "requirements_firefox.txt": [
"c59351ba1a28c84d3db1b95b560988d119393ad3", "176705f3af508acb3117d73d5ab4f0c306024662",
[] []
], ],
"requirements_ie.txt": [ "requirements_ie.txt": [
@ -348932,8 +348975,12 @@
"bf829d93e968d4a6bccfa6798fb974bf98ff7d60", "bf829d93e968d4a6bccfa6798fb974bf98ff7d60",
[] []
], ],
"actions.py": [
"fc43dd665a2f3bc5576cb535f29d49abbc9593fd",
[]
],
"base.py": [ "base.py": [
"ab36c95c11339951c9c5ccd5da4c19551ba8f8de", "5d6c283737e6a768279f69503094345c0f942880",
[] []
], ],
"executorchrome.py": [ "executorchrome.py": [
@ -390944,7 +390991,7 @@
}, },
"css-scrollbars": { "css-scrollbars": {
"auto-scrollbar-inline-children.html": [ "auto-scrollbar-inline-children.html": [
"107938ece14d394e42a5b0d8f3d99d63bf61271e", "149cf942fe625af24de8623baab3e68fed581738",
[ [
null, null,
{} {}
@ -399042,7 +399089,7 @@
] ]
], ],
"outline-width-interpolation.html": [ "outline-width-interpolation.html": [
"c024c7cf6a08e0f6e02ccb451ca04d0b4a8c9251", "a46907a169074b9af0ac85d7f39ebc0e568f8c64",
[ [
null, null,
{} {}
@ -399317,7 +399364,7 @@
] ]
], ],
"outline-width-computed.html": [ "outline-width-computed.html": [
"33eb9c9b99cba713d282010e4ddd5293b7b00aac", "abd5826bbb387ec6dcbebfcd9e2870df8aea6ab9",
[ [
null, null,
{} {}
@ -445861,7 +445908,7 @@
] ]
], ],
"cache-storage-reporting-dedicated-worker.https.html": [ "cache-storage-reporting-dedicated-worker.https.html": [
"c9c2a9ac715658dc8c7a1d5f66bf0e8d93912aa4", "d88bf56ec2cb16dc3ab03035a0bdf15f10f54c04",
[ [
null, null,
{ {
@ -445870,7 +445917,7 @@
] ]
], ],
"cache-storage-reporting-document.https.html": [ "cache-storage-reporting-document.https.html": [
"d5ae757facfc5742a1bbb134dbd67bd6fbdeb4df", "efb7e7a779587de7f5c142383d36470a54908f5c",
[ [
null, null,
{ {
@ -445879,16 +445926,14 @@
] ]
], ],
"cache-storage-reporting-service-worker.https.html": [ "cache-storage-reporting-service-worker.https.html": [
"6b5b78bba088671d4d6eb5b7833bf1c873963eee", "b9ec8d95a59ade8a8120a0af04248d3c930c1dac",
[ [
null, null,
{ {}
"timeout": "long"
}
] ]
], ],
"cache-storage-reporting-shared-worker.https.html": [ "cache-storage-reporting-shared-worker.https.html": [
"0b13de8657f93aeba0980831f98e378b753f4c83", "d7bd191a84e9c2e5b766ea258ac615791471fb95",
[ [
null, null,
{ {
@ -445998,6 +446043,15 @@
} }
] ]
], ],
"reporting-subresource-corp.https.html": [
"aa76bbe8d21d259ed0b9dcadb1d942635134ac79",
[
null,
{
"timeout": "long"
}
]
],
"reporting.https.html": [ "reporting.https.html": [
"42d5e6cc33537e988daf77d740fdcdeab64508c5", "42d5e6cc33537e988daf77d740fdcdeab64508c5",
[ [
@ -453158,6 +453212,13 @@
{} {}
] ]
], ],
"iframe-loading-lazy-referrerpolicy-change.sub.tentative.html": [
"145df404003cdb3ee1c0688351a5300603780789",
[
null,
{}
]
],
"iframe-nosrc.html": [ "iframe-nosrc.html": [
"57189a0b884d3a55e4bb2ba1a1d3aa83066c0eb3", "57189a0b884d3a55e4bb2ba1a1d3aa83066c0eb3",
[ [
@ -453814,7 +453875,7 @@
] ]
], ],
"image-loading-lazy-crossorigin-change.sub.html": [ "image-loading-lazy-crossorigin-change.sub.html": [
"13560324854dceeca26bda3433301cafe07fb62a", "3fb827df2d6159de73c9fe0417cf790d0d484ff6",
[ [
null, null,
{} {}
@ -453883,6 +453944,13 @@
{} {}
] ]
], ],
"image-loading-lazy-referrerpolicy-change.sub.html": [
"307d9571b498e108f121b97f02dc56412cd6f21e",
[
null,
{}
]
],
"image-loading-lazy-srcset.html": [ "image-loading-lazy-srcset.html": [
"21c11c7233c7b8f845a31b6aa25dda14ca381960", "21c11c7233c7b8f845a31b6aa25dda14ca381960",
[ [
@ -454002,13 +454070,6 @@
{} {}
] ]
], ],
"original-referrer-policy-applied.sub.html": [
"c300119f72fbd3742d6dbf7e2439d967911303a5",
[
null,
{}
]
],
"picture-loading-lazy.html": [ "picture-loading-lazy.html": [
"0ab2fb27367309814094071ccad7fa2922aa80f9", "0ab2fb27367309814094071ccad7fa2922aa80f9",
[ [
@ -458310,7 +458371,7 @@
] ]
], ],
"referrer-origin-when-cross-origin.sub.html": [ "referrer-origin-when-cross-origin.sub.html": [
"4cd427ee88766f7f836ef86a3617244864ac5e40", "fd4c1ea49649cf348d99ab0d881aa8f966be416e",
[ [
null, null,
{} {}
@ -463231,7 +463292,7 @@
] ]
], ],
"protocol.https.html": [ "protocol.https.html": [
"d8b3e55d751e34cae2fdcdc356ddb88d79b1f2a8", "d8e064d66fa3870bbdab5636394aca8fa4bf6f9e",
[ [
null, null,
{} {}
@ -487047,6 +487108,13 @@
{} {}
] ]
], ],
"finish-animation.html": [
"87bcc41a6a222d883ebe2b249ae103b05275019d",
[
null,
{}
]
],
"idlharness.window.js": [ "idlharness.window.js": [
"90157580ce00716403346f369b1e25bba8db23c2", "90157580ce00716403346f369b1e25bba8db23c2",
[ [
@ -511214,7 +511282,7 @@
] ]
], ],
"RTCPeerConnection-addIceCandidate-timing.https.html": [ "RTCPeerConnection-addIceCandidate-timing.https.html": [
"d89f353a89fe7d47017583832d2fd080629e7ffd", "9793844f56900927447f080ebbc92011d601fb9d",
[ [
null, null,
{} {}
@ -544952,7 +545020,7 @@
] ]
], ],
"ruby-reflow-001-noruby.html": [ "ruby-reflow-001-noruby.html": [
"4c00573422b3954853965a3d86ad1464a53a244f", "eda07deddb2d5ec93f45675854998f2b27d5a683",
[ [
null, null,
{} {}

View file

@ -0,0 +1,2 @@
[border-top-applies-to-009.xht]
expected: CRASH

View file

@ -0,0 +1,4 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -2,6 +2,3 @@
[Hit test intersecting scaled box] [Hit test intersecting scaled box]
expected: FAIL expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -254,3 +254,75 @@
[CSS Transitions: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]] [CSS Transitions: property <outline-width> from [unset\] to [20px\] at (1.5) should be [28px\]]
expected: FAIL expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (-0.3) should be [0px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (1) should be [23px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0.3) should be [9px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [unset\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL
[Web Animations: property <outline-width> from [initial\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (0) should be [3px\]]
expected: FAIL
[Web Animations: property <outline-width> from [unset\] to [23px\] at (0.6) should be [15px\]]
expected: FAIL
[CSS Animations: property <outline-width> from [initial\] to [23px\] at (1.5) should be [33px\]]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -315,12 +315,21 @@
[<iframe>: separate response Content-Type: text/html;x=" text/plain] [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain] [<iframe>: combined response Content-Type: */* text/html]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk] [<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL

View file

@ -59,9 +59,6 @@
[separate text/javascript;charset=windows-1252 error text/javascript] [separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL expected: FAIL
[separate text/javascript; charset=windows-1252 text/javascript] [separate text/javascript error]
expected: FAIL
[separate text/javascript;charset=windows-1252 text/javascript]
expected: FAIL expected: FAIL

View file

@ -8,6 +8,6 @@
[X-Content-Type-Options%3A%20nosniff%0C] [X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_2.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_5.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
type: testharness type: testharness
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,4 +0,0 @@
[original-referrer-policy-applied.sub.html]
[Test that when deferred img is loaded, it uses the referrer-policy specified at parse time.]
expected: FAIL

View file

@ -0,0 +1,5 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,12 @@
<!doctype html>
<title>overflow-y: scroll on an empty element doesn't cause it to gain height</title>
<link rel="help" href="https://drafts.csswg.org/css-overflow/#propdef-overflow-y">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1365806">
<link rel="match" href="/css/reference/blank.html">
<style>
div {
background: red;
overflow-y: scroll;
}
</style>
<div></div>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<link rel="help" href="https://www.w3.org/TR/css-position-3/" />
<meta name="assert" content="This test checks that a dynamic OOF-positioned change doesn't cause children to paint differently." />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="display: flex; position: relative; width: 100px; height: 100px;">
<div style="order: 2; margin-left: -100px; width: 100px; background: green;"></div>
<div style="order: 1; width: 100px; background: red;"></div>
<div id="target" style="position: absolute;"></div>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.top = '10px';
</script>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<link rel="help" href="https://www.w3.org/TR/css-position-3/" />
<meta name="assert" content="This test checks that a dynamic change in constraints calculates the static position correctly for flex children."/>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="display: flex; position: relative; width: 100px; height: 100px; background: red; align-items: flex-end;">
<div id="target" style="position: absolute; width: 100px; height: 100px; background: green; bottom: 100px;"></div>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.bottom = 'initial';
</script>

View file

@ -2,7 +2,7 @@
<html style="overflow:hidden;"> <html style="overflow:hidden;">
<head> <head>
<title>CSS Test: Ruby Base Frames Reflowed</title> <title>CSS Test: Ruby Base Frames Reflowed</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/"> <link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/">
<meta name="assert" content="Test checks that ruby bases are reflowed."> <meta name="assert" content="Test checks that ruby bases are reflowed.">

View file

@ -2,7 +2,7 @@
<html style="overflow:hidden;"> <html style="overflow:hidden;">
<head> <head>
<title>CSS Test: Ruby Text Frames Visible</title> <title>CSS Test: Ruby Text Frames Visible</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/"> <link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/">
<link rel="mismatch" href="ruby-reflow-001-noruby.html"> <link rel="mismatch" href="ruby-reflow-001-noruby.html">

View file

@ -2,7 +2,7 @@
<html style="overflow:hidden;"> <html style="overflow:hidden;">
<head> <head>
<title>CSS Test: Ruby Base Frames Reflowed</title> <title>CSS Test: Ruby Base Frames Reflowed</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/"> <link rel="help" href="http://www.w3.org/TR/2014/WD-css-ruby-1-20140805/">
<link rel="match" href="ruby-reflow-001-noruby.html"> <link rel="match" href="ruby-reflow-001-noruby.html">

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Ruby whitespace handling</title> <title>Ruby whitespace handling</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="stylesheet" href="support/ruby-common.css"> <link rel="stylesheet" href="support/ruby-common.css">
<style> <style>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Ruby whitespace handling</title> <title>Ruby whitespace handling</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-ruby-1/#white-space"> <link rel="help" href="https://drafts.csswg.org/css-ruby-1/#white-space">
<link rel="match" href="ruby-whitespace-001-ref.html"> <link rel="match" href="ruby-whitespace-001-ref.html">

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Ruby whitespace handling</title> <title>Ruby whitespace handling</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="stylesheet" href="support/ruby-common.css"> <link rel="stylesheet" href="support/ruby-common.css">

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Ruby whitespace handling</title> <title>Ruby whitespace handling</title>
<link rel="author" title="Susanna Bowen" href="mailto:sgbowen8@gmail.com"> <link rel="author" title="Sam Bowen" href="mailto:sgbowen8@gmail.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org"> <link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-ruby-1/#white-space"> <link rel="help" href="https://drafts.csswg.org/css-ruby-1/#white-space">
<link rel="match" href="ruby-whitespace-002-ref.html"> <link rel="match" href="ruby-whitespace-002-ref.html">

View file

@ -9,7 +9,7 @@
.container { width:100px; } .container { width:100px; }
</style> </style>
<p>There should be a blue rectangle below, and possibly a scrollbar (depending <p>There should be a blue rectangle below, and possibly a scrollbar (depending
on OS / browser), that shouldn not obscure any parts of the rectangle. The on OS / browser), that should not obscure any parts of the rectangle. The
word "FAIL" should not be seen.</p> word "FAIL" should not be seen.</p>
<div class="container" style="overflow:auto; height:200px;"> <div class="container" style="overflow:auto; height:200px;">
<div id="child" style="display:inline-block; box-sizing:border-box; width:100%; height:100%; border:10px solid blue;"></div> <div id="child" style="display:inline-block; box-sizing:border-box; width:100%; height:100%; border:10px solid blue;"></div>

View file

@ -55,14 +55,14 @@ test_interpolation({
test_interpolation({ test_interpolation({
property: 'outline-width', property: 'outline-width',
from: 'initial', from: 'initial',
to: '20px', to: '23px',
}, [ }, [
{at: -0.3, expect: '0px'}, {at: -0.3, expect: '0px'},
{at: 0, expect: '3px'}, {at: 0, expect: '3px'},
{at: 0.3, expect: '8px'}, {at: 0.3, expect: '9px'},
{at: 0.6, expect: '13px'}, {at: 0.6, expect: '15px'},
{at: 1, expect: '20px'}, {at: 1, expect: '23px'},
{at: 1.5, expect: '28px'}, {at: 1.5, expect: '33px'},
]); ]);
test_interpolation({ test_interpolation({
@ -81,14 +81,14 @@ test_interpolation({
test_interpolation({ test_interpolation({
property: 'outline-width', property: 'outline-width',
from: 'unset', from: 'unset',
to: '20px', to: '23px',
}, [ }, [
{at: -0.3, expect: '0px'}, {at: -0.3, expect: '0px'},
{at: 0, expect: '3px'}, {at: 0, expect: '3px'},
{at: 0.3, expect: '8px'}, {at: 0.3, expect: '9px'},
{at: 0.6, expect: '13px'}, {at: 0.6, expect: '15px'},
{at: 1, expect: '20px'}, {at: 1, expect: '23px'},
{at: 1.5, expect: '28px'}, {at: 1.5, expect: '33px'},
]); ]);
test_interpolation({ test_interpolation({

View file

@ -24,6 +24,7 @@
</style> </style>
<div id="target"></div> <div id="target"></div>
<script> <script>
test_computed_value("outline-width", "2.5px");
test_computed_value("outline-width", "10px"); test_computed_value("outline-width", "10px");
test_computed_value("outline-width", "0.5em", "20px"); test_computed_value("outline-width", "0.5em", "20px");
test_computed_value("outline-width", "calc(10px + 0.5em)", "30px"); test_computed_value("outline-width", "calc(10px + 0.5em)", "30px");

View file

@ -17,40 +17,30 @@
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = local(encode(worker_path + header_coep)); const worker_url = local(encode(worker_path + header_coep));
const iframe_url = const worker = new Worker(worker_url);
local(encode(iframe_path + header_coep + header_report_to)); const mc = new MessageChannel();
dedicated_worker_script = ` worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
(async function() { const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
const w = new Worker('${worker_url}'); assert_equals(reports.length, 1);
w.postMessage(\`${eval_script}\`); const report = reports[0];
})(); assert_equals(report.body["blocked-url"], image_url);
`; assert_equals(report.body.type, "corp");
const iframe = await makeIframe(t, iframe_url); assert_equals(report.type, "coep");
iframe.contentWindow.postMessage(dedicated_worker_script); assert_equals(report.url, worker_url);
const report = await fetchReport();
assert_equals(report["body"]["blocked-url"], image_url.toString());
assert_equals(report["body"]["type"], "corp");
assert_equals(report["type"], "coep");
assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
}, "COEP support on DedicatedWorker.") }, "COEP support on DedicatedWorker.")
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = local(encode(worker_path + header_coep_report_only)); const worker_url = local(encode(worker_path + header_coep_report_only));
const iframe_url = const worker = new Worker(worker_url);
local(encode(iframe_path + header_coep_report_only + header_report_to)); const mc = new MessageChannel();
dedicated_worker_script = ` worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
(async function() { const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
const w = new Worker('${worker_url}'); assert_equals(reports.length, 1);
w.postMessage(\`${eval_script}\`); const report = reports[0];
})(); assert_equals(report.body["blocked-url"], image_url);
`; assert_equals(report.body.type, "corp");
const iframe = await makeIframe(t, iframe_url); assert_equals(report.type, "coep");
iframe.contentWindow.postMessage(dedicated_worker_script); assert_equals(report.url, worker_url);
const report = await fetchReport();
assert_equals(report["body"]["blocked-url"], image_url.toString());
assert_equals(report["body"]["type"], "corp");
assert_equals(report["type"], "coep");
assert_equals(normalize(report["url"]), normalize(worker_url.toString()));
}, "COEP-Report-Only support on DedicatedWorker.") }, "COEP-Report-Only support on DedicatedWorker.")
</script> </script>

View file

@ -9,34 +9,45 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script> <script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script> <script src="/common/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js">
</script> </script>
<script src="./resources/cache-storage-reporting.js"></script> <script src="./resources/cache-storage-reporting.js"></script>
</head> </head>
<script> <script>
async function waitReports(frame) {
return await new Promise((resolve) => {
const observer = new frame.contentWindow.ReportingObserver((reports) => {
observer.disconnect();
resolve(reports.map(r => r.toJSON()));
});
observer.observe();
frame.contentWindow.eval(eval_script);
});
}
promise_test(async (t) => { promise_test(async (t) => {
const iframe_url = const iframe_url = local(encode(iframe_path + header_coep));
local(encode(iframe_path + header_coep + header_report_to));
const iframe = await makeIframe(t, iframe_url); const iframe = await makeIframe(t, iframe_url);
iframe.contentWindow.postMessage(eval_script); const reports = await waitReports(iframe);
const report = await fetchReport(); assert_equals(reports.length, 1);
assert_equals(report["body"]["blocked-url"], image_url.toString()); const report = reports[0];
assert_equals(report["body"]["type"], "corp"); assert_equals(report.body["blocked-url"], image_url);
assert_equals(report["type"], "coep"); assert_equals(report.body.type, "corp");
assert_equals(normalize(report["url"]), normalize(iframe_url.toString())); assert_equals(report.type, "coep");
assert_equals(report.url, iframe_url);
}, "COEP support on document.") }, "COEP support on document.")
promise_test(async (t) => { promise_test(async (t) => {
const iframe_url = const iframe_url = local(encode(iframe_path + header_coep_report_only));
local(encode(iframe_path + header_coep_report_only + header_report_to));
const iframe = await makeIframe(t, iframe_url); const iframe = await makeIframe(t, iframe_url);
iframe.contentWindow.postMessage(eval_script); const reports = await waitReports(iframe);
const report = await fetchReport(); assert_equals(reports.length, 1);
assert_equals(report["body"]["blocked-url"], image_url.toString()); const report = reports[0];
assert_equals(report["body"]["type"], "corp"); assert_equals(report.body["blocked-url"], image_url);
assert_equals(report["type"], "coep"); assert_equals(report.body.type, "corp");
assert_equals(normalize(report["url"]), normalize(iframe_url.toString())); assert_equals(report.type, "coep");
assert_equals(report.url, iframe_url);
}, "COEP-Report-Only support on document.") }, "COEP-Report-Only support on document.")
</script> </script>

View file

@ -4,7 +4,6 @@
<title> <title>
Check COEP report are send for CacheStorage requests in ServiceWorker. Check COEP report are send for CacheStorage requests in ServiceWorker.
</title> </title>
<meta name="timeout" content="long">
<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/get-host-info.sub.js"></script> <script src="/common/get-host-info.sub.js"></script>
@ -16,38 +15,46 @@
<script> <script>
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = local(encode( const worker_url = local(encode(worker_path + header_coep));
worker_path + header_coep + header_report_to + header_service_worker_allowed // As we don't want the service worker to control any page, generate a
)); // one-time scope.
const SCOPE = new URL(`resources/${token()}.html`, location).pathname;
const reg = const reg =
await service_worker_unregister_and_register(t, worker_url, SW_SCOPE); await service_worker_unregister_and_register(t, worker_url, SCOPE);
add_completion_callback(() => reg.unregister()); add_completion_callback(() => reg.unregister());
const worker = reg.installing || reg.waiting || reg.active; const worker = reg.installing || reg.waiting || reg.active;
reports = fetchReport(); const mc = new MessageChannel();
worker.postMessage(eval_script); worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
const report = await reports; const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
assert_equals(report["body"]["blocked-url"], image_url.toString()); assert_not_equals(reports, 'TIMEOUT');
assert_equals(report["body"]["type"], "corp"); assert_equals(reports.length, 1);
assert_equals(report["type"], "coep"); const report = reports[0];
assert_equals(normalize(report["url"]), normalize(worker_url.toString())); assert_equals(report.body["blocked-url"], image_url);
}, "COEP support on ServiceWorker.") assert_equals(report.body.type, "corp");
assert_equals(report.type, "coep");
assert_equals(report.url, worker_url);
}, "COEP support on ServiceWorker.");
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = local(encode( const worker_url = local(encode(worker_path + header_coep_report_only));
worker_path + header_coep_report_only + header_report_to + header_service_worker_allowed // As we don't want the service worker to control any page, generate a
)) // one-time scope.
const SCOPE = new URL(`resources/${token()}.html`, location).pathname;
const reg = const reg =
await service_worker_unregister_and_register(t, worker_url, SW_SCOPE); await service_worker_unregister_and_register(t, worker_url, SCOPE);
add_completion_callback(() => reg.unregister()); add_completion_callback(() => reg.unregister());
const worker = reg.installing || reg.waiting || reg.active; const worker = reg.installing || reg.waiting || reg.active;
reports = fetchReport(); const mc = new MessageChannel();
worker.postMessage(eval_script); worker.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
const report = await reports; const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
assert_equals(report["body"]["blocked-url"], image_url.toString()); assert_not_equals(reports, 'TIMEOUT');
assert_equals(report["body"]["type"], "corp"); assert_equals(reports.length, 1);
assert_equals(report["type"], "coep"); const report = reports[0];
assert_equals(normalize(report["url"]), normalize(worker_url.toString())); assert_equals(report.body["blocked-url"], image_url);
}, "COEP-Report-Only support on ServiceWorker.") assert_equals(report.body.type, "corp");
assert_equals(report.type, "coep");
assert_equals(report.url, worker_url);
}, "COEP-Report-Only support on ServiceWorker.");
</script> </script>
</html> </html>

View file

@ -2,43 +2,44 @@
<html> <html>
<head> <head>
<title> <title>
Check COEP report are send for CacheStorage requests in DedicatedWorker Check COEP report are send for CacheStorage requests in SharedWorker
</title> </title>
<meta name="timeout" content="long"> <meta name="timeout" content="long">
<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/get-host-info.sub.js"></script> <script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script> <script src="/common/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js">
</script>
<script src="./resources/cache-storage-reporting.js"> </script> <script src="./resources/cache-storage-reporting.js"> </script>
</head> </head>
<script> <script>
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = const worker_url = local(encode(worker_path + header_coep));
local(encode(worker_path + header_coep + header_report_to)); const worker = new SharedWorker(worker_url);
const worker = new Worker(worker_url); const mc = new MessageChannel();
worker.postMessage(eval_script); worker.port.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
const report = await fetchReport(); const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
assert_equals(report["body"]["blocked-url"], image_url.toString()); assert_equals(reports.length, 1);
assert_equals(report["body"]["type"], "corp"); const report = reports[0];
assert_equals(report["type"], "coep"); assert_equals(report.body["blocked-url"], image_url);
assert_equals(normalize(report["url"]), normalize(worker_url.toString())); assert_equals(report.body.type, "corp");
assert_equals(report.type, "coep");
assert_equals(report.url, worker_url);
}, "COEP support on SharedWorker.") }, "COEP support on SharedWorker.")
promise_test(async (t) => { promise_test(async (t) => {
const worker_url = const worker_url = local(encode(worker_path + header_coep_report_only));
local(encode(worker_path + header_coep_report_only + header_report_to)); const worker = new SharedWorker(worker_url);
const worker = new Worker(worker_url); const mc = new MessageChannel();
worker.postMessage(eval_script); worker.port.postMessage({script: eval_script, port: mc.port2}, [mc.port2]);
const report = await fetchReport(); const reports = (await new Promise(r => mc.port1.onmessage = r)).data;
assert_equals(report["body"]["blocked-url"], image_url.toString()); assert_equals(reports.length, 1);
assert_equals(report["body"]["type"], "corp"); const report = reports[0];
assert_equals(report["type"], "coep"); assert_equals(report.body["blocked-url"], image_url);
assert_equals(normalize(report["url"]), normalize(worker_url.toString())); assert_equals(report.body.type, "corp");
assert_equals(report.type, "coep");
assert_equals(report.url, worker_url);
}, "COEP-Report-Only support on SharedWorker.") }, "COEP-Report-Only support on SharedWorker.")
</script> </script>
</html> </html>

View file

@ -0,0 +1,161 @@
<!doctype html>
<html>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const BASE = new URL("resources", location).pathname
const FRAME_URL = `${ORIGIN}/common/blank.html` +
'?pipe=header(cross-origin-embedder-policy,require-corp)' +
`|header(cross-origin-embedder-policy-report-only,require-corp)`;
const WORKER_URL = `${ORIGIN}${BASE}/reporting-worker.js` +
'?pipe=header(cross-origin-embedder-policy,require-corp)' +
`|header(cross-origin-embedder-policy-report-only,require-corp)`;
function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}
function checkReport(report, contextUrl, blockedUrl) {
assert_equals(report.type, 'coep');
assert_equals(report.url, contextUrl);
assert_equals(report.body.type, 'corp');
assert_equals(report.body['blocked-url'], blockedUrl);
}
async function fetchInFrame(t, url) {
const reports = [];
const frame = await with_iframe(FRAME_URL);
t.add_cleanup(() => frame.remove());
const observer = new frame.contentWindow.ReportingObserver((rs) => {
for (const report of rs) {
reports.push(report.toJSON());
}
});
observer.observe();
const init = { mode: 'no-cors', cache: 'no-store' };
await frame.contentWindow.fetch(url, init).catch(() => {});
// Wait 200ms for reports to settle.
await wait(200);
return reports;
}
async function fetchInWorker(workerOrPort, url) {
const script =
`fetch('${url}', {mode: 'no-cors', cache: 'no-store'}).catch(() => {});`;
const mc = new MessageChannel();
workerOrPort.postMessage({script, port: mc.port2}, [mc.port2]);
return (await new Promise(r => mc.port1.onmessage = r)).data;
}
// We want to test several URLs in various environments (document,
// dedicated worker, shared worser, service worker). As expectations
// are independent of environment except for the context URLs in reports,
// we define ENVIRONMENTS and CASES to reduce the code duplication.
//
// ENVIRONMENTS is a list of dictionaries. Each dictionary consists of:
// - tag: the name of the environment
// - contextUrl: the URL of the environment settings object
// - run: an async function which generates reports
// - test: a testharness Test object
// - url: the URL for a test case (see below)
//
// CASES is a list of test cases. Each test case consists of:
// - name: the name of the test case
// - url: the URL of the test case
// - check: a function to check the results
// - reports: the generated reports
// - url: the URL of the test case
// - contextUrl: the URL of the environment settings object (see
// ENVORONMENTS)
const ENVIRONMENTS = [{
tag: 'document',
contextUrl: FRAME_URL,
run: async (test, url) => {
return await fetchInFrame(test, url);
},
}, {
tag: 'dedicated worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
const worker = new Worker(WORKER_URL);
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
test.add_cleanup(() => worker.terminate());
return await fetchInWorker(worker, url);
},
}, {
tag: 'shared worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
const worker = new SharedWorker(WORKER_URL);
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
return await fetchInWorker(worker.port, url);
},
}, {
tag: 'service worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
// As we don't want the service worker to control any page, generate a
// one-time scope.
const SCOPE = new URL(`resources/${token()}.html`, location).pathname;
const reg =
await service_worker_unregister_and_register(test, WORKER_URL, SCOPE);
test.add_cleanup(() => reg.unregister());
const worker = reg.installing || reg.waiting || reg.active;
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
return await fetchInWorker(worker, url);
},
}];
const CASES = [{
name: 'same-origin',
url: '/common/text-plain.txt',
check: (reports, url, contextUrl) => {
assert_equals(reports.length, 0);
}
}, {
name: 'blocked by CORP: same-origin',
url: `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt`,
check: (reports, url, contextUrl) => {
assert_equals(reports.length, 0);
}
}, {
name: 'blocked due to COEP',
url: `${REMOTE_ORIGIN}/common/text-plain.txt`,
check: (reports, contextUrl, url) => {
// One for COEP, one for COEP-RO.
assert_equals(reports.length, 2);
checkReport(reports[0], contextUrl, url);
checkReport(reports[1], contextUrl, url);
}
}, {
name: 'blocked during redirect',
url: `${ORIGIN}/common/redirect.py?location=` +
encodeURIComponent(`${REMOTE_ORIGIN}/common/text-plain.txt`),
check: (reports, contextUrl, url) => {
// One for COEP, one for COEP-RO.
assert_equals(reports.length, 2);
checkReport(reports[0], contextUrl, url);
checkReport(reports[1], contextUrl, url);
},
}];
for (const env of ENVIRONMENTS) {
for (const testcase of CASES) {
promise_test(async (t) => {
const reports = await env.run(t, testcase.url);
testcase.check(reports, env.contextUrl, testcase.url);
}, `[${env.tag}] ${testcase.name}`);
}
}
</script>

View file

@ -1,42 +1,24 @@
function remote(path) { function remote(path) {
const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN; const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
return new URL(path, REMOTE_ORIGIN); return new URL(path, REMOTE_ORIGIN).href;
} }
function local(path) { function local(path) {
return new URL(path, location.origin); return new URL(path, location.origin).href;
} }
let encode = function(url) { function encode(url) {
return encodeURI(url).replace(/\;/g,"%3B"); return encodeURI(url).replace(/\;/g, '%3B');
} }
const resource_path = (new URL("./resources", location)).pathname; const resource_path = (new URL('./resources', location)).pathname;
const report_token= token(); const header_coep = '|header(Cross-Origin-Embedder-Policy,require-corp)';
const report_endpoint_url = local(resource_path + `/report.py?key=${report_token}`)
const endpoint =
{
"group":"endpoint",
"max_age":3600,
"endpoints":[{ "url":report_endpoint_url.toString() }]
};
let endpoint_string =
JSON.stringify(endpoint)
.replace(/,/g, "\\,")
.replace(/\(/g, "\\\(")
.replace(/\)/g, "\\\)=");
const header_report_to = `|header(report-to,${endpoint_string})`;
const header_coep =
'|header(Cross-Origin-Embedder-Policy,require-corp;report-to="endpoint")';
const header_coep_report_only = const header_coep_report_only =
'|header(Cross-Origin-Embedder-Policy-Report-Only,require-corp;report-to="endpoint")'; '|header(Cross-Origin-Embedder-Policy-Report-Only,require-corp)';
const SW_SCOPE = local(resource_path + "/");
const header_service_worker_allowed =
`|header(service-worker-allowed,${SW_SCOPE})`;
const iframe_path = resource_path + "/iframe.html?pipe="; const iframe_path = resource_path + '/iframe.html?pipe=';
const worker_path = resource_path + "/universal-worker.js?pipe="; const worker_path = resource_path + '/reporting-worker.js?pipe=';
const image_url = remote("/images/blue.png"); const image_url = remote('/images/blue.png');
// This script attempt to load a COEP:require-corp CORP:undefined response from // This script attempt to load a COEP:require-corp CORP:undefined response from
// the CacheStorage. // the CacheStorage.
@ -61,13 +43,13 @@ const eval_script = `
promise_setup(async (t) => { promise_setup(async (t) => {
const cache = await caches.open('v1'); const cache = await caches.open('v1');
const fetch_request = new Request(image_url, {mode: 'no-cors'}); const request = new Request(image_url, {mode: 'no-cors'});
const fetch_response = await fetch(fetch_request); const response = await fetch(request);
await cache.put(fetch_request, fetch_response); await cache.put(request, response);
}, "Setup: store a CORS:cross-origin COEP:none response into CacheStorage") }, 'Setup: store a CORS:cross-origin COEP:none response into CacheStorage')
async function makeIframe(test, iframe_url) { async function makeIframe(test, iframe_url) {
const iframe = document.createElement("iframe"); const iframe = document.createElement('iframe');
test.add_cleanup(() => iframe.remove()); test.add_cleanup(() => iframe.remove());
iframe.src = iframe_url; iframe.src = iframe_url;
const iframe_loaded = new Promise(resolve => iframe.onload = resolve); const iframe_loaded = new Promise(resolve => iframe.onload = resolve);
@ -79,26 +61,3 @@ async function makeIframe(test, iframe_url) {
function wait(ms) { function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms)); return new Promise(resolve => step_timeout(resolve, ms));
} }
async function fetchReport() {
const fetch_report_path = resource_path + `/report.py?key=${report_token}`;
while(true) {
const response = await fetch(encode(fetch_report_path));
const reports = await response.json();
if (reports.length == 0) {
wait(200);
continue;
}
if (reports.length != 1)
throw "Too many reports received";
return reports[0];
}
throw "Report not send";
}
// Remove parts of the URL that are different at runtime.
function normalize(url) {
url = new URL(url);
return url.origin + url.pathname;
}

View file

@ -0,0 +1,25 @@
function run({script, port}) {
const reports = [];
const observer = new ReportingObserver((rs) => {
for (const r of rs) {
reports.push(r.toJSON());
}
});
// Wait 200ms for reports to settle.
setTimeout(() => {
observer.disconnect();
port.postMessage(reports);
}, 200);
observer.observe();
// This eval call may generate some reports.
eval(script);
}
// For DedicatedWorker and ServiceWorker
self.addEventListener('message', (e) => run(e.data));
// For SharedWorker
self.addEventListener('connect', (e) => {
e.ports[0].onmessage = (ev) => run(ev.data);
});

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<head>
<title>Deferred loading=lazy iframes are fetched with the parse-time
`referrerpolicy` attribute</title>
<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
<link rel="author" title="Raj T" href="mailto:rajendrant@chromium.org">
<link rel="help" href="https://github.com/scott-little/lazyload">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../the-img-element/common.js"></script>
</head>
<script>
const below_viewport_iframe = new ElementLoadPromise("below_viewport_iframe");
async_test(function(t) {
// Change the referrer-policy and scroll down to load the deferred elements.
window.addEventListener("load", t.step_func(() => {
below_viewport_iframe.element().referrerPolicy = "no-referrer";
below_viewport_iframe.element().scrollIntoView();
}));
below_viewport_iframe.promise.then(
t.step_func_done(function() {
// The `Referer` header should be the full URL, as specified by the
// iframe's `referrerpolicy` attribute at parse-time, and not the origin
// (as specified in meta referrer tag) or null (as overridden
// referrerpolicy=no-referrer after load deferral).
assert_true(below_viewport_iframe.element().contentDocument.body.innerHTML
.includes("Referer: http://{{location[host]}}{{location[path]}}"),
"The iframe's `Referer` should be the referrer's full URL");
}));
}, "Test that when a deferred iframe is fetched, it uses the " +
"`referrerpolicy` specified at parse-time");
</script>
<body>
<meta name="referrer" content="origin">
<div style="height:1000vh;"></div>
<iframe id="below_viewport_iframe" src="/xhr/resources/echo-headers.py"
loading="lazy" width="200px" height="100px"
referrerpolicy="unsafe-url"
onload="below_viewport_iframe.resolve();">
</iframe>
</body>

View file

@ -9,22 +9,32 @@
</head> </head>
<script> <script>
const crossorigin_img = new ElementLoadPromise("crossorigin_img"); const img = new ElementLoadPromise("cross-origin");
// Set the crossorigin attribute and scroll down to load the deferred image.
window.addEventListener("load", () => {
crossorigin_img.element().crossOrigin = 'anonymous';
crossorigin_img.element().scrollIntoView();
});
async_test(function(t) { async_test(function(t) {
crossorigin_img.promise.then(t.unreached_func("The image should not load.")).catch(t.step_func_done()); window.addEventListener("load", t.step_func(() => {
// At this point the image's #updating-the-image-data algorithm has been
// invoked, and the image request has been deferred. The deferred
// cross-origin image request was created with the `no-cors` request mode,
// which would succeed to load the cross-origin image.
// While the request is deferred, we'll set the `crossorigin` attribute to a
// value that would cause the image request to fail. Since `crossorigin`
// mutations trigger another #updating-the-image-data invocation (replacing
// the first one), when we scroll the image into view, the image should be
// fetched with the latest `crossorigin` attribute value, and fail to load.
img.element().crossOrigin = 'anonymous';
img.element().scrollIntoView();
}));
img.promise
.then(t.unreached_func("The image should not load."))
.catch(t.step_func_done());
}, "Test that when deferred image is loaded, it uses the latest crossorigin attribute."); }, "Test that when deferred image is loaded, it uses the latest crossorigin attribute.");
</script> </script>
<body> <body>
<div style="height:1000vh;"></div> <div style="height:1000vh;"></div>
<img id="crossorigin_img" loading="lazy" <img id="cross-origin" loading="lazy"
src='http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/embedded-content/the-img-element/resources/image.png' src='http://{{hosts[alt][]}}:{{ports[http][0]}}/html/semantics/embedded-content/the-img-element/resources/image.png'
onload="crossorigin_img.resolve();" onerror="crossorigin_img.reject();"> onload="img.resolve();" onerror="img.reject();">
</body> </body>

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<head>
<title>Deferred loading=lazy images are fetched with the latest
`referrerpolicy` attribute</title>
<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
<link rel="author" title="Raj T" href="mailto:rajendrant@chromium.org">
<link rel="help" href="https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="common.js"></script>
</head>
<script>
const below_viewport_img = new ElementLoadPromise("below_viewport_img");
async_test(function(t) {
// At this point the image's #updating-the-image-data algorithm has been
// invoked, and the image request has been deferred. The deferred request
// was created with the default referrer policy, which will result in a
// `Referer` header being sent when the request is finally made. The request
// is also for an image that the server will send a broken response for if
// the request has a `Referer` header.
// While the request is deferred, we'll set the `referrerpolicy` attribute
// to `no-referrer`, which would cause the image request to succeed. Since
// `referrerpolicy` mutations trigger another #updating-the-image-data
// invocation (replacing the first one), when we scroll the image into view,
// the image should be fetched with no `Referer` header, and succeed.
window.addEventListener("load", t.step_func(() => {
below_viewport_img.element().referrerPolicy = "no-referrer";
below_viewport_img.element().scrollIntoView();
}));
below_viewport_img.promise
.then(t.step_func_done())
.catch(t.unreached_func("The image request should successfully load"))
}, "Test that when a deferred image is loaded, it uses the latest referrerpolicy");
</script>
<body>
<div style="height:1000vh;"></div>
<img id="below_viewport_img"
src="resources/referrer-checker-img.py?expected_referrer="
loading="lazy" referrerpolicy="unsafe-url"
onload="below_viewport_img.resolve();"
onerror="below_viewport_img.reject();">
</body>

View file

@ -1,51 +0,0 @@
<!DOCTYPE html>
<head>
<title>Deferred iframes and images with loading='lazy' use the original referrer-policy specified at the parse time</title>
<link rel="author" title="Raj T" href="mailto:rajendrant@chromium.org">
<link rel="help" href="https://github.com/scott-little/lazyload">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="common.js"></script>
</head>
<script>
const below_viewport_iframe = new ElementLoadPromise("below_viewport_iframe");
const below_viewport_img = new ElementLoadPromise("below_viewport_img");
// Change the referrer-policy and scroll down to load the deferred elements.
window.addEventListener("load", () => {
below_viewport_iframe.element().referrerPolicy = "no-referrer";
below_viewport_img.element().referrerPolicy = "no-referrer";
document.getElementById("below_viewport_iframe").scrollIntoView();
});
async_test(function(t) {
below_viewport_iframe.promise.then(
t.step_func_done(function() {
// The referer header should be the full URL (as specified in the iframe
// at parse time), and not the origin (as specified in meta referrer
// tag) or null (as overridden by iframe referrerpolicy=no-referrer).
assert_true(below_viewport_iframe.element().contentDocument.body.innerHTML
.includes("Referer: http://{{location[host]}}{{location[path]}}"));
}));
}, "Test that when deferred iframe is loaded, it uses the referrer-policy specified at parse time.");
async_test(function(t) {
below_viewport_img.promise.then(
t.step_func_done(function() {
// The image will load successfully if the full URL is sent as referrer.
assert_true(below_viewport_img.element().complete);
assert_greater_than(below_viewport_img.element().naturalWidth, 0);
})
).catch(t.unreached_func("The image load should not fail, by sending the wrong referer header."));
}, "Test that when deferred img is loaded, it uses the referrer-policy specified at parse time.");
</script>
<body>
<meta name="referrer" content="origin">
<div style="height:10000px;"></div>
<iframe id="below_viewport_iframe" src="/xhr/resources/echo-headers.py" loading="lazy" width="200px" height="100px" referrerpolicy="unsafe-url" onload="below_viewport_iframe.resolve();">
</iframe>
<img id="below_viewport_img" src="resources/referrer-checker-img.py?expected_referrer=http://{{location[host]}}{{location[path]}}"
loading="lazy" referrerpolicy="unsafe-url" onload="below_viewport_img.resolve();" onerror="below_viewport_img.reject();">
</body>

View file

@ -24,7 +24,7 @@ import { referrer as referrerRemoteRemote } from "http://{{domains[www1]}}:{{por
import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same"; import { referrer as referrerRemoteSame } from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/module/resources/import-same-origin-referrer-checker-from-remote-origin.sub.js?name=remote_same";
const origin = (new URL(location.href)).origin + "/"; const origin = (new URL(location.href)).origin + "/";
const remoteOrigin = "http://{{domains[www1]}}:{{ports[http][0]}}/"; const remoteOrigin = new URL("http://{{domains[www1]}}:{{ports[http][0]}}/").origin + "/";
test(t => { test(t => {
assert_equals( assert_equals(

View file

@ -59,7 +59,7 @@ test(() => {
test(() => { test(() => {
assert_throws_dom('SYNTAX_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); }); assert_throws_dom('SYNTAX_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); });
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('x', url, 'foo'); }); assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler('x', url, 'foo'); });
}, `unregisterProtocolHandler: Invalid URL "${url}" should throw (but after scheme)`); }, `unregisterProtocolHandler: Invalid URL "${url}" should throw (but after scheme)`);
}); });
@ -74,14 +74,16 @@ test(() => {
`ftp://${location.host}/%s`, `ftp://${location.host}/%s`,
`chrome://${location.host}/%s`, `chrome://${location.host}/%s`,
`foo://${location.host}/%s`, `foo://${location.host}/%s`,
URL.createObjectURL(new Blob()) + "#%s",
].forEach(url => { ].forEach(url => {
const title = url.startsWith("blob:") ? "blob: URL" : url;
test(() => { test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); }); assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); });
}, 'registerProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.'); }, `registerProtocolHandler: Invalid URL "${title}" should throw SECURITY_ERR.`);
test(() => { test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); }); assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); });
}, 'unregisterProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.'); }, `unregisterProtocolHandler: Invalid URL "${title}" should throw SECURITY_ERR.`);
}); });
/* Protocol argument */ /* Protocol argument */

View file

@ -298,6 +298,7 @@ SET TIMEOUT: html/browsers/windows/auxiliary-browsing-contexts/resources/close-o
SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-none.sub.html SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-none.sub.html
SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-require-corp.sub.html SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-require-corp.sub.html
SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-require-corp-same-site.sub.html SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-require-corp-same-site.sub.html
SET TIMEOUT: html/cross-origin-embedder-policy/resources/reporting-worker.js
SET TIMEOUT: html/dom/documents/dom-tree-accessors/Document.currentScript.html SET TIMEOUT: html/dom/documents/dom-tree-accessors/Document.currentScript.html
SET TIMEOUT: html/webappapis/timers/* SET TIMEOUT: html/webappapis/timers/*
SET TIMEOUT: orientation-event/resources/orientation-event-helpers.js SET TIMEOUT: orientation-event/resources/orientation-event-helpers.js

View file

@ -0,0 +1,342 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Finishing an animation</title>
<link rel="help"
href="https://drafts.csswg.org/web-animations/#finishing-an-animation-section">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="testcommon.js"></script>
<style>
.scroller {
overflow: auto;
height: 200px;
width: 100px;
}
.contents {
height: 1000px;
width: 100%;
}
</style>
<body>
<div id="log"></div>
<script>
'use strict';
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.playbackRate = 0;
assert_throws_dom('InvalidStateError', () => {
animation.finish();
});
}, 'Finishing an animation with a zero playback rate throws');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
animation.effect.updateTiming({ iterations : Infinity });
animation.play();
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_throws_dom('InvalidStateError', () => {
animation.finish();
});
}, 'Finishing an infinite animation throws');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.finish();
assert_times_equal(animation.currentTime, 1000,
'After finishing, the currentTime should be set to the end of the'
+ ' active duration');
}, 'Finishing an animation seeks to the end time');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
// 1s past effect end
animation.currentTime =
animation.effect.getComputedTiming().endTime + 1;
animation.finish();
assert_time_equals_literal(animation.currentTime, 1000,
'After finishing, the currentTime should be set back to the end of the'
+ ' active duration');
}, 'Finishing an animation with a current time past the effect end jumps'
+ ' back to the end');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.currentTime = 1000;
await animation.finished;
animation.playbackRate = -1;
animation.finish();
assert_equals(animation.currentTime, 0,
'After finishing a reversed animation the currentTime ' +
'should be set to zero');
}, 'Finishing a reversed animation jumps to zero time');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.currentTime = 1000;
await animation.finished;
animation.playbackRate = -1;
animation.currentTime = -10000;
animation.finish();
assert_equals(animation.currentTime, 0,
'After finishing a reversed animation the currentTime ' +
'should be set back to zero');
}, 'Finishing a reversed animation with a current time less than zero'
+ ' makes it jump back to zero');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.playbackRate = 0.5;
animation.finish();
assert_false(animation.pending);
assert_equals(animation.playState, 'finished',
'The play state of a play-pending animation should become ' +
'"finished"');
assert_times_equal(animation.startTime,
animation.timeline.currentTime - 1000 / 0.5,
'The start time of a play-pending animation should ' +
'be set');
}, 'Finishing an animation while play-pending resolves the pending'
+ ' task immediately');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
scroller.scrollTop;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.finish();
await animation.finished;
assert_true(animation.pending);
assert_equals(animation.playState, 'finished',
'The play state of a play-pending animation should become ' +
'"finished"');
assert_times_equal(animation.currentTime, 1000,
'The current time of a play-pending animation should ' +
'be set to the end of the active duration');
assert_equals(animation.startTime, null,
'The start time of a finished play-pending animation' +
' should be be unresolved');
}, 'Finishing an animation attached to inactive timeline while play-pending '
+ 'doesn\'t resolves the pending task');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
let resolvedFinished = false;
animation.finished.then(() => {
resolvedFinished = true;
});
await animation.ready;
animation.finish();
await Promise.resolve();
assert_true(resolvedFinished, 'finished promise should be resolved');
}, 'Finishing an animation resolves the finished promise synchronously');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
const promise = animation.ready;
let readyResolved = false;
animation.finish();
animation.ready.then(() => { readyResolved = true; });
const promiseResult = await animation.finished;
await animation.ready;
assert_equals(promiseResult, animation);
assert_equals(animation.ready, promise);
assert_true(readyResolved);
}, 'A pending ready promise is resolved and not replaced when the animation'
+ ' is finished');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.effect.target.remove();
const eventWatcher = new EventWatcher(t, animation, 'finish');
await animation.ready;
animation.finish();
await eventWatcher.wait_for('finish');
assert_equals(animation.effect.target.parentNode, null,
'finish event should be fired for the animation on an orphaned element');
}, 'Finishing an animation fires finish event on orphaned element');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
const originalFinishPromise = animation.finished;
animation.cancel();
assert_equals(animation.startTime, null);
assert_equals(animation.currentTime, null);
const resolvedFinishPromise = animation.finished;
assert_true(originalFinishPromise != resolvedFinishPromise,
'Canceling an animation should create a new finished promise');
animation.finish();
assert_equals(animation.playState, 'finished',
'The play state of a canceled animation should become ' +
'"finished"');
assert_times_equal(animation.startTime,
animation.timeline.currentTime - 1000,
'The start time of a finished animation should be set');
assert_times_equal(animation.currentTime, 1000,
'Hold time should be set to end boundary of the animation');
}, 'Finishing a canceled animation sets the current and start times');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
const eventWatcher = new EventWatcher(t, animation, 'finish');
animation.finish();
await animation.finished;
const finishEvent = await eventWatcher.wait_for('finish');
assert_equals(animation.playState, 'finished',
'Animation is finished.');
assert_equals(animation.currentTime, 1000,
'The current time is the end of the active duration in finished state.');
assert_equals(animation.startTime, -750,
'The start time is calculated to match the current time.');
assert_equals(finishEvent.currentTime, 1000,
'event.currentTime is the animation current time.');
assert_equals(finishEvent.timelineTime, 250,
'event.timelineTime is timeline.currentTime');
}, 'Finishing idle animation produces correct state and fires finish event.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive.');
animation.finish();
assert_equals(animation.playState, 'paused', 'Animation is paused.');
}, 'Finishing idle animation attached to inactive timeline pauses the ' +
'animation.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
const eventWatcher = new EventWatcher(t, animation, 'finish');
animation.finish();
await animation.finished;
const finishEvent = await eventWatcher.wait_for('finish');
assert_equals(animation.playState, 'finished',
'Animation is finished.');
assert_equals(animation.currentTime, 1000,
'The current time is the end of active duration in finished state.');
assert_equals(animation.startTime, -750,
'The start time is calculated to match animation current time.');
assert_equals(finishEvent.currentTime, 1000,
'event.currentTime is the animation current time.');
assert_equals(finishEvent.timelineTime, 250,
'event.timelineTime is timeline.currentTime');
}, 'Finishing running animation produces correct state and fires finish event.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
scroller.scrollTop;
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive.');
assert_equals(animation.playState, 'running',
'Sanity check the animation is running.');
animation.finish();
assert_equals(animation.playState, 'paused', 'Animation is paused.');
}, 'Finishing running animation attached to inactive timeline pauses the ' +
'animation.');
</script>
</body>

View file

@ -230,6 +230,7 @@ tasks:
-- --
--channel=${vars.channel} --channel=${vars.channel}
--verify --verify
--verify-no-chaos-mode
- wpt-${vars.browser}-${vars.channel}-results: - wpt-${vars.browser}-${vars.channel}-results:
use: use:

View file

@ -18,8 +18,7 @@ from .utils import call, get, untar, unzip
uname = platform.uname() uname = platform.uname()
# the rootUrl for the firefox-ci deployment of Taskcluster # the rootUrl for the firefox-ci deployment of Taskcluster
# (after November 9, https://firefox-ci-tc.services.mozilla.com/) FIREFOX_CI_ROOT_URL = 'https://firefox-ci-tc.services.mozilla.com'
FIREFOX_CI_ROOT_URL = 'https://taskcluster.net'
def _get_fileversion(binary, logger=None): def _get_fileversion(binary, logger=None):
@ -49,6 +48,15 @@ def get_ext(filename):
return ext return ext
def get_taskcluster_artifact(index, path):
TC_INDEX_BASE = FIREFOX_CI_ROOT_URL + "/api/index/v1/"
resp = get(TC_INDEX_BASE + "task/%s/artifacts/%s" % (index, path))
resp.raise_for_status()
return resp
class Browser(object): class Browser(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
@ -174,7 +182,7 @@ class Firefox(Browser):
url = "https://download.mozilla.org/?product=%s&os=%s&lang=en-US" % (product[channel], url = "https://download.mozilla.org/?product=%s&os=%s&lang=en-US" % (product[channel],
os_builds[os_key]) os_builds[os_key])
self.logger.info("Downloading Firefox from %s" % url) self.logger.info("Downloading Firefox from %s" % url)
resp = requests.get(url) resp = get(url)
filename = None filename = None
@ -413,32 +421,32 @@ class Firefox(Browser):
return find_executable(os.path.join(dest, "geckodriver")) return find_executable(os.path.join(dest, "geckodriver"))
def install_geckodriver_nightly(self, dest): def install_geckodriver_nightly(self, dest):
import tarfile
import mozdownload
self.logger.info("Attempting to install webdriver from nightly") self.logger.info("Attempting to install webdriver from nightly")
try:
s = mozdownload.DailyScraper(branch="mozilla-central", platform_bits = ("64" if uname[4] == "x86_64" else
extension="common.tests.tar.gz", ("32" if self.platform == "win" else ""))
destination=dest) tc_platform = "%s%s" % (self.platform, platform_bits)
package_path = s.download()
except mozdownload.errors.NotFoundError: archive_ext = ".zip" if uname[0] == "Windows" else ".tar.gz"
return archive_name = "public/geckodriver%s" % archive_ext
try: try:
exe_suffix = ".exe" if uname[0] == "Windows" else "" resp = get_taskcluster_artifact(
with tarfile.open(package_path, "r") as f: "gecko.v2.mozilla-central.latest.geckodriver.%s" % tc_platform,
try: archive_name)
member = f.getmember("bin%sgeckodriver%s" % (os.path.sep, except Exception:
exe_suffix)) self.logger.info("Geckodriver download failed")
except KeyError:
return return
# Remove bin/ from the path.
member.name = os.path.basename(member.name) if archive_ext == ".zip":
f.extractall(members=[member], path=dest) unzip(resp.raw, dest)
path = os.path.join(dest, member.name) else:
untar(resp.raw, dest)
exe_ext = ".exe" if uname[0] == "Windows" else ""
path = os.path.join(dest, "geckodriver%s" % exe_ext)
self.logger.info("Extracted geckodriver to %s" % path) self.logger.info("Extracted geckodriver to %s" % path)
finally:
os.unlink(package_path)
return path return path
@ -461,24 +469,10 @@ class FirefoxAndroid(Browser):
if dest is None: if dest is None:
dest = os.pwd dest = os.pwd
if FIREFOX_CI_ROOT_URL == 'https://taskcluster.net':
# NOTE: this condition can be removed after November 9, 2019
TC_QUEUE_BASE = "https://queue.taskcluster.net/v1/"
TC_INDEX_BASE = "https://index.taskcluster.net/v1/"
else:
TC_QUEUE_BASE = FIREFOX_CI_ROOT_URL + "/api/queue/v1/"
TC_INDEX_BASE = FIREFOX_CI_ROOT_URL + "/api/index/v1/"
resp = get_taskcluster_artifact(
resp = requests.get(TC_INDEX_BASE + "gecko.v2.mozilla-central.latest.mobile.android-x86_64-opt",
"task/gecko.v2.mozilla-central.latest.mobile.android-x86_64-opt") "public/build/geckoview-androidTest.apk")
resp.raise_for_status()
index = resp.json()
task_id = index["taskId"]
resp = requests.get(TC_QUEUE_BASE + "task/%s/artifacts/%s" %
(task_id, "public/build/geckoview-androidTest.apk"))
resp.raise_for_status()
filename = "geckoview-androidTest.apk" filename = "geckoview-androidTest.apk"
if rename: if rename:

View file

@ -52,7 +52,6 @@
"parser": "get_parser", "parser": "get_parser",
"help": "Install browser components", "help": "Install browser components",
"install": [ "install": [
"mozdownload",
"mozinstall" "mozinstall"
] ]
}, },

View file

@ -1,6 +1,5 @@
marionette_driver==3.0.0 marionette_driver==3.0.0
mozcrash==2.0.0 mozcrash==2.0.0
mozdownload==1.26.0
mozinstall==2.0.0 mozinstall==2.0.0
mozleak==0.2 mozleak==0.2
moznetwork==1.1.0 moznetwork==1.1.0

View file

@ -0,0 +1,184 @@
class ClickAction(object):
name = "click"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
selector = payload["selector"]
element = self.protocol.select.element_by_selector(selector)
self.logger.debug("Clicking element: %s" % selector)
self.protocol.click.element(element)
class SendKeysAction(object):
name = "send_keys"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
selector = payload["selector"]
keys = payload["keys"]
element = self.protocol.select.element_by_selector(selector)
self.logger.debug("Sending keys to element: %s" % selector)
self.protocol.send_keys.send_keys(element, keys)
class ActionSequenceAction(object):
name = "action_sequence"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
# TODO: some sort of shallow error checking
actions = payload["actions"]
for actionSequence in actions:
if actionSequence["type"] == "pointer":
for action in actionSequence["actions"]:
if (action["type"] == "pointerMove" and
isinstance(action["origin"], dict)):
action["origin"] = self.get_element(action["origin"]["selector"], action["frame"]["frame"])
self.protocol.action_sequence.send_actions({"actions": actions})
def get_element(self, element_selector, frame):
element = self.protocol.select.element_by_selector(element_selector, frame)
return element
class GenerateTestReportAction(object):
name = "generate_test_report"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
message = payload["message"]
self.logger.debug("Generating test report: %s" % message)
self.protocol.generate_test_report.generate_test_report(message)
class SetPermissionAction(object):
name = "set_permission"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
permission_params = payload["permission_params"]
descriptor = permission_params["descriptor"]
name = descriptor["name"]
state = permission_params["state"]
one_realm = permission_params.get("oneRealm", False)
self.logger.debug("Setting permission %s to %s, oneRealm=%s" % (name, state, one_realm))
self.protocol.set_permission.set_permission(descriptor, state, one_realm)
class AddVirtualAuthenticatorAction(object):
name = "add_virtual_authenticator"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
self.logger.debug("Adding virtual authenticator")
config = payload["config"]
authenticator_id = self.protocol.virtual_authenticator.add_virtual_authenticator(config)
self.logger.debug("Authenticator created with ID %s" % authenticator_id)
return authenticator_id
class RemoveVirtualAuthenticatorAction(object):
name = "remove_virtual_authenticator"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Removing virtual authenticator %s" % authenticator_id)
return self.protocol.virtual_authenticator.remove_virtual_authenticator(authenticator_id)
class AddCredentialAction(object):
name = "add_credential"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
credential = payload["credential"]
self.logger.debug("Adding credential to virtual authenticator %s " % authenticator_id)
return self.protocol.virtual_authenticator.add_credential(authenticator_id, credential)
class GetCredentialsAction(object):
name = "get_credentials"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Getting credentials from virtual authenticator %s " % authenticator_id)
return self.protocol.virtual_authenticator.get_credentials(authenticator_id)
class RemoveCredentialAction(object):
name = "remove_credential"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
credential_id = payload["credential_id"]
self.logger.debug("Removing credential %s from authenticator %s" % (credential_id, authenticator_id))
return self.protocol.virtual_authenticator.remove_credential(authenticator_id, credential_id)
class RemoveAllCredentialsAction(object):
name = "remove_all_credentials"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Removing all credentials from authenticator %s" % authenticator_id)
return self.protocol.virtual_authenticator.remove_all_credentials(authenticator_id)
class SetUserVerifiedAction(object):
name = "set_user_verified"
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
uv = payload["uv"]
self.logger.debug(
"Setting user verified flag on authenticator %s to %s" % (authenticator_id, uv["isUserVerified"]))
return self.protocol.virtual_authenticator.set_user_verified(authenticator_id, uv)
actions = [ClickAction,
SendKeysAction,
ActionSequenceAction,
GenerateTestReportAction,
SetPermissionAction,
AddVirtualAuthenticatorAction,
RemoveVirtualAuthenticatorAction,
AddCredentialAction,
GetCredentialsAction,
RemoveCredentialAction,
RemoveAllCredentialsAction,
SetUserVerifiedAction]

View file

@ -13,6 +13,7 @@ from six.moves.http_client import HTTPConnection
from six.moves.urllib.parse import urljoin, urlsplit, urlunsplit from six.moves.urllib.parse import urljoin, urlsplit, urlunsplit
from ..testrunner import Stop from ..testrunner import Stop
from .actions import actions
from .protocol import Protocol, BaseProtocolPart from .protocol import Protocol, BaseProtocolPart
here = os.path.split(__file__)[0] here = os.path.split(__file__)[0]
@ -681,20 +682,7 @@ class CallbackHandler(object):
"complete": self.process_complete "complete": self.process_complete
} }
self.actions = { self.actions = {cls.name: cls(self.logger, self.protocol) for cls in actions}
"click": ClickAction(self.logger, self.protocol),
"send_keys": SendKeysAction(self.logger, self.protocol),
"action_sequence": ActionSequenceAction(self.logger, self.protocol),
"generate_test_report": GenerateTestReportAction(self.logger, self.protocol),
"set_permission": SetPermissionAction(self.logger, self.protocol),
"add_virtual_authenticator": AddVirtualAuthenticatorAction(self.logger, self.protocol),
"remove_virtual_authenticator": RemoveVirtualAuthenticatorAction(self.logger, self.protocol),
"add_credential": AddCredentialAction(self.logger, self.protocol),
"get_credentials": GetCredentialsAction(self.logger, self.protocol),
"remove_credential": RemoveCredentialAction(self.logger, self.protocol),
"remove_all_credentials": RemoveAllCredentialsAction(self.logger, self.protocol),
"set_user_verified": SetUserVerifiedAction(self.logger, self.protocol),
}
def __call__(self, result): def __call__(self, result):
url, command, payload = result url, command, payload = result
@ -735,150 +723,3 @@ class CallbackHandler(object):
def _send_message(self, message_type, status, message=None): def _send_message(self, message_type, status, message=None):
self.protocol.testdriver.send_message(message_type, status, message=message) self.protocol.testdriver.send_message(message_type, status, message=message)
class ClickAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
selector = payload["selector"]
element = self.protocol.select.element_by_selector(selector)
self.logger.debug("Clicking element: %s" % selector)
self.protocol.click.element(element)
class SendKeysAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
selector = payload["selector"]
keys = payload["keys"]
element = self.protocol.select.element_by_selector(selector)
self.logger.debug("Sending keys to element: %s" % selector)
self.protocol.send_keys.send_keys(element, keys)
class ActionSequenceAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
# TODO: some sort of shallow error checking
actions = payload["actions"]
for actionSequence in actions:
if actionSequence["type"] == "pointer":
for action in actionSequence["actions"]:
if (action["type"] == "pointerMove" and
isinstance(action["origin"], dict)):
action["origin"] = self.get_element(action["origin"]["selector"], action["frame"]["frame"])
self.protocol.action_sequence.send_actions({"actions": actions})
def get_element(self, element_selector, frame):
element = self.protocol.select.element_by_selector(element_selector, frame)
return element
class GenerateTestReportAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
message = payload["message"]
self.logger.debug("Generating test report: %s" % message)
self.protocol.generate_test_report.generate_test_report(message)
class SetPermissionAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
permission_params = payload["permission_params"]
descriptor = permission_params["descriptor"]
name = descriptor["name"]
state = permission_params["state"]
one_realm = permission_params.get("oneRealm", False)
self.logger.debug("Setting permission %s to %s, oneRealm=%s" % (name, state, one_realm))
self.protocol.set_permission.set_permission(descriptor, state, one_realm)
class AddVirtualAuthenticatorAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
self.logger.debug("Adding virtual authenticator")
config = payload["config"]
authenticator_id = self.protocol.virtual_authenticator.add_virtual_authenticator(config)
self.logger.debug("Authenticator created with ID %s" % authenticator_id)
return authenticator_id
class RemoveVirtualAuthenticatorAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Removing virtual authenticator %s" % authenticator_id)
return self.protocol.virtual_authenticator.remove_virtual_authenticator(authenticator_id)
class AddCredentialAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
credential = payload["credential"]
self.logger.debug("Adding credential to virtual authenticator %s " % authenticator_id)
return self.protocol.virtual_authenticator.add_credential(authenticator_id, credential)
class GetCredentialsAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Getting credentials from virtual authenticator %s " % authenticator_id)
return self.protocol.virtual_authenticator.get_credentials(authenticator_id)
class RemoveCredentialAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
credential_id = payload["credential_id"]
self.logger.debug("Removing credential %s from authenticator %s" % (credential_id, authenticator_id))
return self.protocol.virtual_authenticator.remove_credential(authenticator_id, credential_id)
class RemoveAllCredentialsAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
self.logger.debug("Removing all credentials from authenticator %s" % authenticator_id)
return self.protocol.virtual_authenticator.remove_all_credentials(authenticator_id)
class SetUserVerifiedAction(object):
def __init__(self, logger, protocol):
self.logger = logger
self.protocol = protocol
def __call__(self, payload):
authenticator_id = payload["authenticator_id"]
uv = payload["uv"]
self.logger.debug(
"Setting user verified flag on authenticator %s to %s" % (authenticator_id, uv["isUserVerified"]))
return self.protocol.virtual_authenticator.set_user_verified(authenticator_id, uv)

View file

@ -92,4 +92,58 @@ promise_test(async t => {
}, 'addIceCandidate and setLocalDescription are resolved in the correct ' + }, 'addIceCandidate and setLocalDescription are resolved in the correct ' +
'order, as defined by the operations chain specification'); 'order, as defined by the operations chain specification');
promise_test(async t => {
const caller = new RTCPeerConnection();
t.add_cleanup(() => caller.close());
const callee = new RTCPeerConnection();
t.add_cleanup(() => callee.close());
caller.addTransceiver('audio');
let events = [];
let pendingPromises = [];
const onCandidatePromise = new Promise(resolve => {
caller.onicecandidate = () => {
events.push('candidate generated');
resolve();
}
});
pendingPromises.push(onCandidatePromise);
pendingPromises.push(caller.setLocalDescription().then(() => {
events.push('setLocalDescription');
}));
await Promise.all(pendingPromises);
assert_array_equals(events, ['setLocalDescription', 'candidate generated']);
}, 'onicecandidate fires after resolving setLocalDescription in offerer');
promise_test(async t => {
const caller = new RTCPeerConnection();
t.add_cleanup(() => caller.close());
const callee = new RTCPeerConnection();
t.add_cleanup(() => callee.close());
caller.addTransceiver('audio');
let events = [];
let pendingPromises = [];
caller.onicecandidate = (ev) => {
if (ev.candidate) {
callee.addIceCandidate(ev.candidate);
}
}
const offer = await caller.createOffer();
const onCandidatePromise = new Promise(resolve => {
callee.onicecandidate = () => {
events.push('candidate generated');
resolve();
}
});
await callee.setRemoteDescription(offer);
const answer = await callee.createAnswer();
pendingPromises.push(onCandidatePromise);
pendingPromises.push(callee.setLocalDescription(answer).then(() => {
events.push('setLocalDescription');
}));
await Promise.all(pendingPromises);
assert_array_equals(events, ['setLocalDescription', 'candidate generated']);
}, 'onicecandidate fires after resolving setLocalDescription in answerer');
</script> </script>