// Register a property, and interpolate its value to the halfway point. function registerAndInterpolateProperty(options) { CSS.registerProperty({ name: options.name, syntax: `${options.syntax} | none`, initialValue: 'none', inherits: false }); let animation = options.on.animate([ { [options.name]: options.from }, { [options.name]: options.to } ], 1000); animation.currentTime = 500; animation.pause(); } // Apply a paint worklet to 'target' which verifies that the worklet-side value // of a set of properties is what we expect. // // The 'expected' parameter is an object where each key is the name of a // property to check, and each corresponding value is an array with the expected // (serialized) values for that property. function expectWorkletValues(target, expected) { const workletName = 'registered-property-value'; // Wrap any single values in an array. This makes it possible to omit the // array if there is only one value. const ensureArray = x => x.constructor === Array ? x : [x]; expected = Object.entries(expected).map(([k, v]) => [k, ensureArray(v)]) .map(x => ({[x[0]]: x[1]})) .reduce((a, b) => Object.assign(a, b), {}); target.style.setProperty('width', '100px'); target.style.setProperty('height', '100px'); target.style.setProperty('background-image', `paint(${workletName})`); const worklet = ` const expectedData = ${JSON.stringify(expected)}; const expectedKeys = Object.keys(expectedData).sort(); registerPaint('${workletName}', class { static get inputProperties() { return expectedKeys; } paint(ctx, geom, styleMap) { let serialize = (v) => '[' + v.constructor.name + ' ' + v.toString() + ']'; let actual = expectedKeys.map(k => styleMap.getAll(k).map(serialize).join(', ')).join(' | '); let expected = expectedKeys.map(k => expectedData[k].join(', ')).join(' | '); ctx.fillStyle = (actual === expected) ? 'green' : 'red'; ctx.fillRect(0, 0, geom.width, geom.height); } });` importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, worklet); } // Like expectWorkletValues, but can only test a single property. function expectWorkletValue(target, property, expected) { expectWorkletValues(target, { [property]: expected }); }