Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev tools Network and Performance #7212

Merged
merged 28 commits into from
May 20, 2019
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
adab44b
Current works
May 15, 2019
75c7f87
Merge pull request #1 from adiohana/javaChromeDevToolsAddPerformaceApi
adiohana May 15, 2019
55e87e0
devtools Network
May 15, 2019
51dd032
Merge pull request #2 from adiohana/dev_tools_network
adiohana May 15, 2019
1438d18
added more parsers
May 15, 2019
50fe76d
Merge pull request #3 from adiohana/dev_tools_network
adiohana May 15, 2019
5d402d2
* Network add Cookies
May 15, 2019
ac2dea4
merge commit
May 15, 2019
503d0d5
added tests changes
May 15, 2019
3e21730
Merge pull request #5 from adiohana/dev_tools_network
adiohana May 15, 2019
3eb305a
added parsers
May 15, 2019
6c79b73
Merge pull request #6 from adiohana/dev_tools_network
adiohana May 15, 2019
bf40dfb
fix merge conflicts
May 15, 2019
ac821ec
Add Methods webSocketClosed , webSocketCreated , webSocketFrameError …
May 16, 2019
8d3fef7
Merge pull request #7 from adiohana/javaChromeDevToolsAddPerformaceApi
adiohana May 16, 2019
2a3dff7
Network methods completed
May 16, 2019
f9a34d6
Merge branch 'master' of https://github.com/adiohana/selenium into ja…
May 16, 2019
93dd215
Merge pull request #8 from adiohana/javaChromeDevToolsAddPerformaceApi
adiohana May 16, 2019
1defb64
finish up
May 16, 2019
eeb5185
fixes according to comments
May 16, 2019
e6622a5
fixes according to comments #2 - null validations
May 16, 2019
1c65237
null validations in all model classes. use Instant for all timestamps.
May 17, 2019
2019545
added test cases
May 17, 2019
cfe501c
use AppServer in devtools test cases. created abstract DevTools base …
May 17, 2019
e581e78
cookie operations will be with Selenium Cookie
May 18, 2019
b810020
added test coverage for Network. changed unsupported methods to private
May 18, 2019
4f76757
added test coverage for Network. support Command List as input
May 19, 2019
38824dc
added copyrights
May 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions common/src/web/postForm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html>
<body>

<form method="post" action="resultPage.html">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably fine now, but prefer creating new pages for tests: there are places where we count elements in tests because we didn't know better when we started writing these things.

<select id="redirect" name="redirect" onchange="javascript:changePage();">
<option selected="selected" value="one">One</option>
<option id="changeme" value="two">Two</option>
</select>

<input type="submit" />
</form>

</body>
</html>
5 changes: 3 additions & 2 deletions java/client/src/org/openqa/selenium/devtools/BUCK
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
java_library(
name = "devtools",
srcs = glob(["*.java"]),
srcs = glob(["**/*.java"]),
deps = [
"//java/client/src/org/openqa/selenium:selenium",
"//java/client/src/org/openqa/selenium/json:json",
Expand All @@ -9,5 +9,6 @@ java_library(
],
visibility = [
"//java/client/src/org/openqa/selenium/remote:",
"//java/client/test/...",
],
)
)
2 changes: 1 addition & 1 deletion java/client/src/org/openqa/selenium/devtools/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
java_library(
name = "devtools",
srcs = glob(["*.java"]),
srcs = glob(["**/*.java"]),
visibility = [
"//java/client/src/org/openqa/selenium/chrome:__pkg__",
"//java/client/src/org/openqa/selenium/remote:__pkg__",
Expand Down
1 change: 0 additions & 1 deletion java/client/src/org/openqa/selenium/devtools/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;

public class Command<X> {
Expand Down
4 changes: 4 additions & 0 deletions java/client/src/org/openqa/selenium/devtools/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ private static Timestamp fromJson(long timestamp) {
return new Timestamp(timestamp);
}

public static Timestamp fromJson(Number timestamp) {
return fromJson(timestamp.longValue());
}

private long toJson() {
return epochMillis;
}
Expand Down
594 changes: 594 additions & 0 deletions java/client/src/org/openqa/selenium/devtools/network/Network.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.openqa.selenium.devtools.network.model;

import static java.util.Objects.requireNonNull;

import org.openqa.selenium.json.JsonInput;

public class AuthChallenge {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can fix this in a later go-round, but we should strive to make data classes immutable. By setting everything in the constructors, we can ensure that class invariants are held true. In this case, the only nullable field in AuthChallenge is the source. Right now, it's possible to create non-valid instances of this class.


/**
* Origin of the challenger.
*/
private String origin;
/**
* The realm of the challenge. May be empty.
*/
private String realm;
/**
* The authentication scheme used, such as basic or digest
*/
private String scheme;
/**
* Source of the authentication challenge.
* Optional
*/
private Source source;

public static AuthChallenge parseRequest(JsonInput input) {
AuthChallenge authChallenge = new AuthChallenge();
input.beginObject();
while (input.hasNext()){
switch (input.nextName()) {
case "origin" :
authChallenge.setOrigin(input.nextString());
break;
case "realm" :
authChallenge.setRealm(input.nextString());
break;
case "scheme" :
authChallenge.setScheme(input.nextString());
break;
case "source" :
authChallenge.setSource(Source.getSource(input.nextString()));
break;
default:
input.skipValue();
break;
}
}
input.endObject();
return authChallenge;
}


public String getScheme() {
return scheme;
}

private void setScheme(String scheme) {
requireNonNull(origin, "'scheme' is mandatory for AuthChallenge");
this.scheme = scheme;
}

public String getOrigin() {
return origin;
}

public void setOrigin(String origin) {
requireNonNull(origin, "'origin' is mandatory for AuthChallenge");
this.origin = origin;
}

public String getRealm() {
return realm;
}

private void setRealm(String realm) {
requireNonNull(origin, "'realm' is mandatory for AuthChallenge");
this.realm = realm;
}

public Source getSource() {
return source;
}

public void setSource(Source source) {
this.source = source;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.openqa.selenium.devtools.network.model;

import java.util.Objects;

/**
* Response to an AuthChallenge
*/
public class AuthChallengeResponse {

/**
* The decision on what to do in response to the authorization challenge. Default means deferring to the default behavior of the net stack,
* which will likely either the Cancel authentication or display a popup dialog box
*/
private final String response;

/**
* The username to provide, possibly empty. Should only be set if response is ProvideCredentials
*/
private final String username;

/**
* The password to provide, possibly empty. Should only be set if response is ProvideCredentials
*/
private final String password;

public AuthChallengeResponse(String response, String username, String password) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great :)

this.response = Objects.requireNonNull(response, "response must be set.");
this.username = username;
this.password = password;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AuthChallengeResponse that = (AuthChallengeResponse) o;
return Objects.equals(response, that.response) &&
Objects.equals(username, that.username) &&
Objects.equals(password, that.password);
}

@Override
public int hashCode() {

return Objects.hash(response, username, password);
}

@Override
public String toString() {
return "AuthChallengeResponse{" +
"response='" + response + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openqa.selenium.devtools.network.model;

/**
* The reason why request was blocked
*/
public enum BlockedReason {

other("other"),
csp("csp"),
mixedContent("mixed-content"),
origin("origin"),
inspector("inspector"),
subresourceFilter("subresource-filter"),
contentType("content-type"),
collapsedbyClient("collapsed-by-client");

private String reason;

BlockedReason(String reason) {
this.reason = reason;
}

public String getReason() {
return reason;
}

public static BlockedReason fromString(String s) {
for (BlockedReason b : BlockedReason.values()) {
if (b.getReason().equalsIgnoreCase(s)) {
return b;
}
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package org.openqa.selenium.devtools.network.model;

import static java.util.Objects.requireNonNull;

import org.openqa.selenium.json.JsonInputConverter;
import org.openqa.selenium.json.JsonInput;

/**
* Stack entry for runtime errors and assertions.
*/
public class CallFrame {

private String functionName;

private String scriptId;

private String url;

private Integer lineNumber;

private Integer columnNumber;

private CallFrame(String functionName, String scriptId, String url, Integer lineNumber,
Integer columnNumber) {
this.functionName = requireNonNull(functionName, "'functionName' is mandatory for CallFrame");
this.scriptId = requireNonNull(scriptId, "'scriptId' is mandatory for CallFrame");
this.url = requireNonNull(url, "'url' is mandatory for CallFrame");
this.lineNumber = requireNonNull(lineNumber, "'lineNumber' is mandatory for CallFrame");
this.columnNumber = requireNonNull(columnNumber, "'columnNumber' is mandatory for CallFrame");
}

/**
* JavaScript function name.
*/
public String getFunctionName() {
return functionName;
}

/**
* JavaScript function name.
*/
public void setFunctionName(String functionName) {
this.functionName = functionName;
}

/**
* JavaScript script id.
*/
public String getScriptId() {
return scriptId;
}

/**
* JavaScript script id.
*/
public void setScriptId(String scriptId) {
this.scriptId = scriptId;
}

/**
* JavaScript script name or url.
*/
public String getUrl() {
return url;
}

/**
* JavaScript script name or url.
*/
public void setUrl(String url) {
this.url = url;
}

/**
* JavaScript script line number (0-based).
*/
public Integer getLineNumber() {
return lineNumber;
}

/**
* JavaScript script line number (0-based).
*/
public void setLineNumber(Integer lineNumber) {
this.lineNumber = lineNumber;
}

/**
* JavaScript script column number (0-based).
*/
public Integer getColumnNumber() {
return columnNumber;
}

/**
* JavaScript script column number (0-based).
*/
public void setColumnNumber(Integer columnNumber) {
this.columnNumber = columnNumber;
}

public static CallFrame parseCallFrame(JsonInput input) {
String functionName = null;
String scriptId = null;
String callFrameUrl = null;
Integer callFrameLineNumber = null;
Integer columnNumber = null;
input.beginObject();
while (input.hasNext()) {
switch (input.nextName()) {
case "functionName":
functionName = input.nextString();
break;
case "scriptId":
scriptId = input.nextString();
break;
case "url":
callFrameUrl = input.nextString();
break;
case "lineNumber":
callFrameLineNumber = JsonInputConverter.extractInt(input);
break;
case "columnNumber":
columnNumber = JsonInputConverter.extractInt(input);
break;
default:
input.skipValue();
break;
}
}
input.endObject();
return new CallFrame(functionName, scriptId, callFrameUrl, callFrameLineNumber, columnNumber);
}
}
Loading