mirror of
https://github.com/microsoft/playwright-java.git
synced 2025-09-08 21:01:00 +00:00
test: convert remaining page.evaluate tests (#62)
This commit is contained in:
parent
4198b39b83
commit
602406b53b
@ -152,8 +152,9 @@ class Serialization {
|
||||
return (T) Double.valueOf(Double.POSITIVE_INFINITY);
|
||||
case "-Infinity":
|
||||
return (T) Double.valueOf(Double.NEGATIVE_INFINITY);
|
||||
case "-0":
|
||||
return (T) Double.valueOf(-0);
|
||||
case "-0": {
|
||||
return (T) Double.valueOf(-0.0);
|
||||
}
|
||||
case "NaN":
|
||||
return (T) Double.valueOf(Double.NaN);
|
||||
default:
|
||||
|
@ -42,8 +42,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldTransfer0() {
|
||||
Object result = page.evaluate("a => a", -0);
|
||||
assertTrue((Integer) result == -0);
|
||||
Object result = page.evaluate("a => a", -0.0);
|
||||
assertEquals(Double.NEGATIVE_INFINITY, 1 / (Double) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -63,7 +63,7 @@ public class TestPageEvaluate extends TestBase {
|
||||
Map<String, ?> value = mapOf(
|
||||
"infinity", Double.POSITIVE_INFINITY,
|
||||
"nInfinity", Double.NEGATIVE_INFINITY,
|
||||
"nZero", -0,
|
||||
"nZero", -0.0,
|
||||
"nan", Double.NaN
|
||||
);
|
||||
Object result = page.evaluate("value => value", value);
|
||||
@ -81,8 +81,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
assertEquals(Double.POSITIVE_INFINITY, result);
|
||||
}
|
||||
{
|
||||
Object result = page.evaluate("value => Promise.resolve(value)", -0);
|
||||
assertEquals(-0, result);
|
||||
Object result = page.evaluate("value => Promise.resolve(value)", -0.0);
|
||||
assertEquals(Double.NEGATIVE_INFINITY, 1 / (Double) result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ public class TestPageEvaluate extends TestBase {
|
||||
Map<String, ?> value = mapOf(
|
||||
"infinity", Double.POSITIVE_INFINITY,
|
||||
"nInfinity", Double.NEGATIVE_INFINITY,
|
||||
"nZero", -0,
|
||||
"nZero", -0.0,
|
||||
"nan", Double.NaN
|
||||
);
|
||||
Object result = page.evaluate("value => Promise.resolve(value)", value);
|
||||
@ -212,4 +212,413 @@ public class TestPageEvaluate extends TestBase {
|
||||
assertTrue(e.getMessage().contains("not_existing_object"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportThrownStringsAsErrorMessages() {
|
||||
try {
|
||||
page.evaluate("() => { throw 'qwerty'; }");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("qwerty"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportThrownNumbersAsErrorMessages() {
|
||||
try {
|
||||
page.evaluate("() => { throw 100500; }");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("100500"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnComplexObjects() {
|
||||
Map<String, ?> object = mapOf("foo", "bar!");
|
||||
Object result = page.evaluate("a => a", object);
|
||||
assertFalse(object == result);
|
||||
assertEquals(object, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnNaN() {
|
||||
Object result = page.evaluate("() => NaN");
|
||||
assertEquals(Double.NaN, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturn0() {
|
||||
Object result = page.evaluate("() => -0");
|
||||
assertEquals(Double.NEGATIVE_INFINITY, 1 / (Double) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnInfinity() {
|
||||
Object result = page.evaluate("() => Infinity");
|
||||
assertEquals(Double.POSITIVE_INFINITY, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnNegativeInfinity() {
|
||||
Object result = page.evaluate("() => -Infinity");
|
||||
assertEquals(Double.NEGATIVE_INFINITY, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithOverwrittenPromise() {
|
||||
page.evaluate("() => {\n" +
|
||||
" const originalPromise = window.Promise;\n" +
|
||||
" class Promise2 {\n" +
|
||||
" static all(arg) {\n" +
|
||||
" return wrap(originalPromise.all(arg));\n" +
|
||||
" }\n" +
|
||||
" static race(arg) {\n" +
|
||||
" return wrap(originalPromise.race(arg));\n" +
|
||||
" }\n" +
|
||||
" static resolve(arg) {\n" +
|
||||
" return wrap(originalPromise.resolve(arg));\n" +
|
||||
" }\n" +
|
||||
" constructor(f) {\n" +
|
||||
" this._promise = new originalPromise(f);\n" +
|
||||
" }\n" +
|
||||
" then(f, r) {\n" +
|
||||
" return wrap(this._promise.then(f, r));\n" +
|
||||
" }\n" +
|
||||
" catch(f) {\n" +
|
||||
" return wrap(this._promise.catch(f));\n" +
|
||||
" }\n" +
|
||||
" finally(f) {\n" +
|
||||
" return wrap(this._promise.finally(f));\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" const wrap = p => {\n" +
|
||||
" const result = new Promise2(() => { });\n" +
|
||||
" result._promise = p;\n" +
|
||||
" return result;\n" +
|
||||
" };\n" +
|
||||
" window.Promise = Promise2;\n" +
|
||||
" window['__Promise2'] = Promise2;\n" +
|
||||
" }");
|
||||
|
||||
// Sanity check.
|
||||
assertEquals(true, page.evaluate("() => {\n" +
|
||||
" const p = Promise.all([Promise.race([]), new Promise(() => { }).then(() => { })]);\n" +
|
||||
" return p instanceof window['__Promise2'];\n" +
|
||||
"}"));
|
||||
|
||||
// Now, the new promise should be awaitable.
|
||||
assertEquals(42, page.evaluate("() => Promise.resolve(42)"));
|
||||
}
|
||||
|
||||
void shouldThrowWhenPassedMoreThanOneParameter() {
|
||||
// Not applicable.
|
||||
}
|
||||
|
||||
void shouldAcceptUndefinedAsOneOfMultipleParameters() {
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProperlySerializeUndefinedArguments() {
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProperlySerializeUndefinedFields() {
|
||||
assertEquals(mapOf("a", null), page.evaluate("() => ({ a: undefined })"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnUndefinedProperties() {
|
||||
Object value = page.evaluate("() => ({ a: undefined })");
|
||||
assertEquals(mapOf("a", null), value);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProperlySerializeNullArguments() {
|
||||
assertEquals(null, page.evaluate("x => x", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProperlySerializeNullFields() {
|
||||
assertEquals(mapOf("a", null), page.evaluate("() => ({ a: null })"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnUndefinedForNonSerializableObjects() {
|
||||
assertEquals(null, page.evaluate("() => window"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailForCircularObject() {
|
||||
Object result = page.evaluate("() => {\n" +
|
||||
" const a = {};\n" +
|
||||
" const b = { a };\n" +
|
||||
" a.b = b;\n" +
|
||||
" return a;\n" +
|
||||
"}");
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeAbleToThrowATrickyError() {
|
||||
JSHandle windowHandle = page.evaluateHandle("() => window");
|
||||
String errorText = null;
|
||||
try {
|
||||
windowHandle.jsonValue();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
errorText = e.getMessage();
|
||||
}
|
||||
assertNotNull(errorText);
|
||||
try {
|
||||
page.evaluate("errorText => {\n" +
|
||||
" throw new Error(errorText);\n" +
|
||||
"}", errorText);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains(errorText));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcceptAString() {
|
||||
Object result = page.evaluate("1 + 2");
|
||||
assertEquals(3, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcceptAStringWithSemiColons() {
|
||||
Object result = page.evaluate("1 + 5;");
|
||||
assertEquals(6, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcceptAStringWithComments() {
|
||||
Object result = page.evaluate("2 + 5;\n// do some math!");
|
||||
assertEquals(7, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcceptElementHandleAsAnArgument() {
|
||||
page.setContent("<section>42</section>");
|
||||
ElementHandle element = page.querySelector("section");
|
||||
Object text = page.evaluate("e => e.textContent", element);
|
||||
assertEquals("42", text);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowIfUnderlyingElementWasDisposed() {
|
||||
page.setContent("<section>39</section>");
|
||||
ElementHandle element = page.querySelector("section");
|
||||
assertNotNull(element);
|
||||
element.dispose();
|
||||
try {
|
||||
page.evaluate("e => e.textContent", element);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("JSHandle is disposed"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSimulateAUserGesture() {
|
||||
assertEquals(true, page.evaluate("() => {\n" +
|
||||
" document.body.appendChild(document.createTextNode('test'));\n" +
|
||||
" document.execCommand('selectAll');\n" +
|
||||
" return document.execCommand('copy');\n" +
|
||||
"}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowANiceErrorAfterANavigation() {
|
||||
try {
|
||||
Deferred<Response> navigation = page.waitForNavigation();
|
||||
page.evaluate("() => {\n" +
|
||||
" const promise = new Promise(f => window['__resolve'] = f);\n" +
|
||||
" window.location.reload();\n" +
|
||||
" setTimeout(() => window['__resolve'](42), 1000);\n" +
|
||||
" return promise;\n" +
|
||||
"}");
|
||||
navigation.get();
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("navigation"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotThrowAnErrorWhenEvaluationDoesANavigation() {
|
||||
page.navigate(server.PREFIX + "/one-style.html");
|
||||
Object result = page.evaluate("() => {\n" +
|
||||
" window.location.href = '/empty.html';\n" +
|
||||
" return [42];\n" +
|
||||
"}");
|
||||
assertEquals(asList(42), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotThrowAnErrorWhenEvaluationDoesASynchronousNavigationAndReturnsAnObject() {
|
||||
// TODO: test.fixme(browserName === "webkit");
|
||||
// It is imporant to be on about:blank for sync reload.
|
||||
Object result = page.evaluate("() => {\n" +
|
||||
" window.location.reload();\n" +
|
||||
" return { a: 42 };\n" +
|
||||
"}");
|
||||
assertEquals(mapOf("a", 42), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotThrowAnErrorWhenEvaluationDoesASynchronousNavigationAndReturnsUndefined() {
|
||||
// It is imporant to be on about:blank for sync reload.
|
||||
Object result = page.evaluate("() => {\n" +
|
||||
" window.location.reload();\n" +
|
||||
" return undefined;\n" +
|
||||
"}");
|
||||
assertEquals(null, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldTransfer100MbOfDataFromPageToNodeJs() {
|
||||
// This is too slow with wire.
|
||||
Object a = page.evaluate("() => Array(100 * 1024 * 1024 + 1).join('a')");
|
||||
String str = (String) a;
|
||||
assertEquals(100 * 1024 * 1024, str.length());
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if ('a' != str.charAt(i)) {
|
||||
fail("Unexpected char at position " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowErrorWithDetailedInformationOnExceptionInsidePromise() {
|
||||
try {
|
||||
page.evaluate("() => new Promise(() => {\n" +
|
||||
" throw new Error('Error in promise');\n" +
|
||||
"})");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Error in promise"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkEvenWhenJSONIsSetToNull() {
|
||||
page.evaluate("() => { window.JSON.stringify = null; window.JSON = null; }");
|
||||
Object result = page.evaluate("() => ({ abc: 123 })");
|
||||
assertEquals(mapOf("abc", 123), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAwaitPromiseFromPopup() {
|
||||
// Something is wrong about the way Firefox waits for the chained promise
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
Object result = page.evaluate("() => {\n" +
|
||||
" const win = window.open('about:blank');\n" +
|
||||
" return new win['Promise'](f => f(42));\n" +
|
||||
"}");
|
||||
assertEquals(42, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithNewFunctionAndCSP() {
|
||||
server.setCSP("/empty.html", "script-src " + server.PREFIX);
|
||||
page.navigate(server.PREFIX + "/empty.html");
|
||||
assertEquals(true, page.evaluate("() => new Function('return true')()"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithNonStrictExpressions() {
|
||||
assertEquals(3.14, page.evaluate("() => {\n" +
|
||||
" y = 3.14;\n" +
|
||||
" return y;\n" +
|
||||
"}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectUseStrictExpression() {
|
||||
try {
|
||||
page.evaluate("() => {\n" +
|
||||
" 'use strict';\n" +
|
||||
" // @ts-ignore\n" +
|
||||
" variableY = 3.14;\n" +
|
||||
" // @ts-ignore\n" +
|
||||
" return variableY;\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("variableY"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotLeakUtilityScript() {
|
||||
assertEquals(true, page.evaluate("() => this === window"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotLeakHandles() {
|
||||
try {
|
||||
page.evaluate("handles.length");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains(" handles"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithCSP() {
|
||||
server.setCSP("/empty.html", "script-src 'self'");
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
assertEquals(4, page.evaluate("() => 2 + 2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldEvaluateException() {
|
||||
try {
|
||||
page.evaluate("() => {\n" +
|
||||
" return (function functionOnStack() {\n" +
|
||||
" return new Error('error message');\n" +
|
||||
" })();\n" +
|
||||
"}");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Error: error message"));
|
||||
assertTrue(e.getMessage().contains("functionOnStack"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldEvaluateException2() {
|
||||
Object error = page.evaluate("new Error('error message')");
|
||||
assertTrue(((String) error).contains("Error: error message"));
|
||||
}
|
||||
|
||||
void shouldEvaluateDate() {
|
||||
// TODO: Date values are not supported in java.
|
||||
}
|
||||
|
||||
void shouldRoundtripDate() {
|
||||
// TODO: Date values are not supported in java.
|
||||
}
|
||||
|
||||
void shouldRoundtripRegex() {
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
void shouldJsonValueDate() {
|
||||
// TODO: Date values are not supported in java.
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotUseToJSONWhenEvaluating() {
|
||||
Object result = page.evaluate("() => ({ toJSON: () => 'string', data: 'data' })");
|
||||
assertEquals(mapOf("data", "data", "toJSON", emptyMap()), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotUseToJSONInJsonValue() {
|
||||
JSHandle resultHandle = page.evaluateHandle("() => ({ toJSON: () => 'string', data: 'data' })");
|
||||
assertEquals(mapOf("data", "data", "toJSON", emptyMap()), resultHandle.jsonValue());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user