seneca-cdot / plumadriver Goto Github PK
View Code? Open in Web Editor NEWA standalone server implementing the W3C WebDriver standard using jsdom
License: MIT License
A standalone server implementing the W3C WebDriver standard using jsdom
License: MIT License
Describe the bug
If no url is provided when creating a session, the dom
object within a Browser
class does not get initialized.
To Reproduce
POST
to /session/
with the following capabilities:
{
"capabilities": {
"firstMatch": [
{
"browserName": "pluma",
"plm:plumaOptions": { "runScripts": false }
}
]
}
}
Describe the results you received:
this.dom
is undefined.
Describe the results you expected:
this.dom
to be set to a default jsdom object.
Additional context
Suspected cause is in Browser.ts
:
this.dom = await new JSDOM(' ', {
resources: config.resourceLoader,
runScripts: config.runScripts,
beforeParse: config.beforeParse,
pretendToBeVisual: true,
cookieJar: config.jar
});
await
on a non-promise may be preventing the value from being set.
What would you like to be added:
The Element Clear
endpoint should be added to PlumaDriver's list of supported endpoints.
Why is this needed:
It is a useful feature that will allow clearing text content from editable or resettable elements.
Additional context
Specification
What would you like to be changed:
Change the existing tests (e.g. validator.js
) to work under Jest.
Why is this needed:
Consolidates all tests under one framework.
Additional context:
Jest's migration documentation suggests using npx jest-codemods
to assist in the conversion.
What would you like to be added:
The command cp -r ./src/jsdom_extensions/ ./build/
found in the build scripts is no longer necessary since typescript has been configured to include this folder on compile (see #38).
Why is this needed:
Reduces build times since the tsc
command already compiles this folder.
Description
.get fails to navigate to a path on the local filesystem. The use case for this is twofold; one, it would be nice to test small items quickly without standing up a web server, and we also have a large offline demo app which displays examples of each of our control types. The test .html page is very basic but I'll attach it anyways. (as .txt since I can't upload an .html)
test.txt
Steps/Code to Reproduce
public static void test(WebDriver driver)
{
driver.get("file://C:/work/test.html");
}
Expected Results
Both ChromeDriver and the PlumaDriver should navigate properly.
Actual Results
ChromeDriver navigates properly. PlumaDriver fails on the get. Stack trace as follows:
stack.txt
Error log:
pluma_error_log.txt
Versions
latest
What happened:
Build process reports many warnings, e.g. Warning Failed to make bytecode latest-x64 for file /snapshot/plumadriver/node_modules/express/index.js
What you expected to happen:
pkg
commands to run without any problems.
How to reproduce it (as minimally and precisely as possible):
Run any one of the four build scripts. (tested not working on both windows and linux)
Anything else we need to know?:
pkg
also seems to have problems with node12
. Changing target build settings results in errors with this version.
What would you like to be added:
A PlumaDriver implementation of the W3C Webdriver Click Endpoint (/session/{session id}/element/{element id}/click
)
Why is this needed:
The ability to fire mouse events is relevant to a large number of webdriver use cases.
What would you like to be added:
import * as foo from foo
to import foo from foo
esModuleInterop
in tsconfig.json
moduleResolution
to 'node'
Why is this needed:
This is recommended by Typescript's documentation as it brings imports closer to intended behaviour.
Additional context
See Typescript's notes.
Driver executable should have an option for the port to listen to. Modify PlumaDriverService class createArgs() method to allow for this.
What would you like to be added:
The click
endpoint ignores elements that would trigger navigation due to jsdom's limitations. Add a way to support this.
Why is this needed:
Click navigation is part of the W3C spec, and would allow implementing some common user interactions (e.g. clicking anchor tags).
Additional context
May involve refactoring click
and clear
logic to be handled by the Browser
.
Description
executeScript returns an empty map instead of null when executing 'return undefined;' or 'return;'
Steps/Code to Reproduce
public static void test(WebDriver driver)
{
driver.get("http://captive.apple.com");
Assert.assertEquals(null, ((JavascriptExecutor)driver).executeScript("return null;"));
Assert.assertEquals(null, ((JavascriptExecutor)driver).executeScript("return undefined;"));
Assert.assertEquals(null, ((JavascriptExecutor)driver).executeScript("return;"));
}
Expected Results
All three asserts should pass in both Chrome and Pluma, since, according to the Selenium Javadoc, "Unless the value is null or there is no return value, in which null is returned"
https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html
Actual Results
All three pass in Chrome. The first passes in Pluma, and the next two fail.
Exception in thread "main" junit.framework.AssertionFailedError: expected: but was:<{}>
at junit.framework.Assert.fail(Assert.java:47)
Versions
Against this build: 21e5022
What would you like to be added:
Add and configure Eslint rules for the following:
typescript
prettier
Add automation for linting rules:
husky
lint-staged
Add linting of commit messages:
commitlint
Why is this needed:
Improves the readability of the code, prevents certain bugs, and ensures that consistent standards are being followed during development.
Our basic strategy was to:
It looks like we're failing on step 4. Replacing PlumaDriver with the Firefox GeckoDriver works properly. I thought maybe this method of getting the cookies was a bit janky, so I replaced it with the 'proper' method; using OkHttp to create a request with the authentication, and parsing out the cookies from the response headers. This gives me the same error. Firefox continues to work.
I've attached a partial stack trace below; if there's any more information you need, please let me know.
org.openqa.selenium.InvalidArgumentException: The arguments passed to undefined are either invalid or malformed
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:48'
System info: host: 'TOR-DT-AJORDAN1', ip: '192.168.61.28', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
Driver info: org.openqa.selenium.chrome.PlumaDriver
Capabilities {acceptInsecureCerts: true, browserName: pluma, browserVersion: v1.0, javascriptEnabled: true, pageLoadStrategy: normal, platform: UNIX, platformName: UNIX, plm:plumaOptions: {}, proxy: Proxy(), setWindowRect: false, timeouts: {implicit: 0, pageLoad: 30000, script: 30000}}
Session ID: 0c9d37b1-82f1-11e9-907f-c1ce7518a251
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebDriver$RemoteWebDriverOptions.addCookie(RemoteWebDriver.java:682)
at nexj.core.testing.ui.application.Application.login(Application.java:604)
at nexj.core.testing.ui.application.AFLApplication.login(AFLApplication.java:174)
at nexj.core.testing.ui.application.AFLApplication.login(AFLApplication.java:145)
In utils.ts
:
let response = null;
const result = await req.session.process(req.sessionRequest);
if (result) {
response = { value: result };
res.json(response);
} else {
res.send(response);
}
Sometimes the endpoint must return null
(e.g. NAVIGATE_TO
), but in some cases it must return explicitly { "value": null }
(e.g. ELEMENT_CLICK
).
As discussed, static type-checking will be useful as the project grows in size.
What happened:
Error executing a synchronous script referencing window
and document
objects.
What you expected to happen:
The ability to use the above objects using the endpoint
How to reproduce it (as minimally and precisely as possible):
In Selenium:
JavascriptExecutor js = (JavascriptExecutor) driver;
String output = (String) js.executeScript("return document.title");
What would you like to be added:
Support strict type checking settings, such as disallowing implicit any
or missing declarations. Change config properties in tsconfig.json
to enable these features (i.e. strict: true
). Make the necessary changes to the codebase to pass checks under these settings.
Why is this needed:
Helps further prevent bugs with more thorough type validation throughout the codebase.
Tasks:
noImplicitAny
@MeisterRedstrictNullChecks
@zthaverstrictPropertyInitialization
@zthaverstrictBindCallApply
@pynnlnoImplicitThis
@pynnlstrictFunctionTypes
@pynnlalwaysStrict
@pynnltsconfig
(should be done after the aboves) @pynnljsdom
and express
, and remove redundancy @pynnlDescription
Exceptions when attempting to return a WebElement as a result of executeScript. The first test should just pass an element in and retrieve that same element. The second test should try to retrieve that same element directly.
Steps/Code to Reproduce
public static void test(WebDriver driver)
{
driver.get("http://captive.apple.com");
WebElement element = driver.findElement(By.tagName("body"));
WebElement e1 = (WebElement)((JavascriptExecutor)driver).executeScript("return arguments[0];", element);
Assert.assertEquals(e1, element);
WebElement e2 = (WebElement)((JavascriptExecutor)driver).executeScript("return document.getElementsByTagName('body')[0];");
Assert.assertEquals(e2, element);
}
Expected Results
Both asserts should pass in Pluma, as they do in Chrome.
Actual Results
Chrome passes. The first test fails with an exception; an error log is generated, but completely empty.
Exception in thread "main" java.lang.ClassCastException: com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to org.openqa.selenium.WebElement
at nexj.core.testing.ui.application.Test.test(Test.java:99)
at nexj.core.testing.ui.application.Test.main(Test.java:31)
The second test throws a very familiar console error, and 'document is not defined' is in the error log.
pluma_error_log_2.txt
output_2.txt
Versions
Against this version: 21e5022
What changes would you like to see:
The legacy
folder can be removed (these files are still accessible in older commits), and perhaps the test_docs
folder as well (need to confirm).
Why is this needed:
Master branch should only contain essential files and folders used for development/production.
What happened:
Execute Script Sync
endpoint does not throw JavascriptError
and ScriptTimeout
when appropriate.
How to reproduce it (as minimally and precisely as possible):
JavaScriptError
: executeScript("return null.foo");
ScriptTimeout
: executeScript("while (true) {}");
What happened:
Attempting to run a global function throws a JavaSciptError: not defined
.
How to reproduce it (as minimally and precisely as possible):
Create a global function foo
within the page, and attempt to call it from executeScript('foo()')
Anything else we need to know?:
This is likely a problem with contextifying the V8 Virtual Machine.
What would you like to be added:
Uninstall packages that are not used in the project. Remove these dependencies from package.json
.
Why is this needed:
Doing so will reduce the application's overhead.
Additional context
npx depcheck
gives the following output. This is not comprehensive or entirely accurate (i.e. some of these are actual dependencies), but it's a starting point.
Unused dependencies
* encodeurl
* express_logger
* os
* request
* validator-js
Unused devDependencies
* @typescript-eslint/eslint-plugin
* @typescript-eslint/parser
* fs
* http-post
* jsdoc
* should
* tslint-eslint-rules
Missing dependencies
* underscore
What would you like to be changed:
Instead of inheriting from WebDriverError
inherit from NotFoundError
.
Why is this needed:
It follows the error hierarchy more accurately.
What would you like to be added:
Delete Cookie
Why is this needed:
It is one of the remaining endpoints associated with Cookie Jar
management.
What would you like to be changed:
In Session.ts
:
async process({
command,
parameters,
urlVariables,
}: Pluma.Request): Promise<string> {
let response = null;
return new Promise(
async (resolve, reject): Promise<void> => ...
Async functions wrap return values in Promises, so this can be omitted.
What would you like to be added:
JavaScriptError
and ScriptTimeoutError
classeswindow
and document
objects in execute script context.jest
tests for endpoint functions.Promise.race()
during script execution)Why is this needed:
To adhere to W3C recommendation, optimize, and prevent future bugs related to the endpoint.
What would you like to be changed:
There is a typo on line 50 of SessionManager.ts
. Add the missing letter in unhandledPromtBehaviour
.
Why is this needed:
This causes the capability to be improperly reported to the client.
the "New Session" /session endpoint currently does not accept capabilities parameters provided by the client (selenium). Need to integrate this to current implementation in order to be W3C compliant.
the GET element attribute endpoint is never called by getAttribute method in Selenium as expected. Instead, the execute script endpoint is called with a function in the request body that handles the logic for getting element attributes. Execute script endpoint must be implemented in order to obtain functionality for this endpoint
What would you like to be added:
isDisplayed: this endpoint determines whether or not an element is visible to the human eye.
Why is this needed:
According to the spec, this is a feature that is important to many users.
Additional context
Reference algorithm
What would you like to be added:
Type checking is done in several places with constructor checks, e.g. this.valid = capability.constructor === Object;
. Suggest replacing with instanceof/typeof
, i.e. this.valid = capability instanceof Object
and/or using Typescript guards
.
Why is this needed:
The constructor property can be mutated, and may be less reliable in some cases.
Additional context
What happened:
Attempting to return false
, ''
, 0
or other falsy values that are not null
or undefined
instead returns null
.
How to reproduce it (as minimally and precisely as possible):
executeScript("return false")
Anything else we need to know?:
Likely caused by the default endpoint logic handler converting falsy values to null
.
What would you like to be added:
The selenium client provides users with an actions object which allows users to send the driver a list of actions to be performed synchronously or asynchronously. This includes, keyUp, keyDown, mouseMove, click, etc. More info on this can be found here
The following seem the most critical and should be implemented first:
Why is this needed:
This is a very powerful feature of selenium and plumadriver would be missing a lot of functionality if this fails to be implemented
Additional context
The Session
class is growing rather large and violating the single-responsibility principle
. Suggest splitting each command into its own module. This will make the code more maintainable and easier to reason about.
The driver currently does not have any logic for handling user prompts when navigating to a url and other endpoints as specified in the w3c webdriver protocol. This needs to be implemented
Describe the bug
runScripts validator expects a boolean:
runScripts(value) {
return value.constructor === Boolean;
},
RunScriptsValues are defined as StringUnion('dangerously', 'outside-only', '')
To Reproduce
Sending a request to /session
with the following JSON produces an error:
{
"capabilities": {
"firstMatch": [
{
"browserName": "pluma",
"plm:plumaOptions": { "runScripts": "dangerously" }
}
]
}
}
Replacing dangerously
with false
creates a session successfully, but node reports an unhandled promise rejection warning.
We need a template to log issues, simplify debugging and make the code base more maintainable. This should at the very least include the following:
any other ideas as to what to include in the template?
Need to create documentation for selenium plumadriver client code. Link needs to be inserted into PlumaDriverService.java findDefaultExecutable() method. Also create executable files, provide download links in methods.
What happened:
Received the following response when using findElement
to find an h1
element:
value: {
element: {},
'element-6066-11e4-a52e-4f735466cecf': '23ad8680-07f8-11ea-a7f8-c5a5f09ee86f'
}
What you expected to happen:
To receive the response:
value: {
'element-6066-11e4-a52e-4f735466cecf': '23ad8680-07f8-11ea-a7f8-c5a5f09ee86f'
}
How to reproduce it (as minimally and precisely as possible):
make a request to the Find Element
endpoint and check the pluma request logs.
Anything else we need to know?:
This breaks the Execute Script Sync
endpoint on certain requests. HTMLElements
will need to be serialized in the proper format.
What would you like to be added:
Get Named Cookie
: returns a cookie with a requested name from the Cookie Jar.
Why is this needed:
It is part of the endpoints needed for cookie management
Additional context
Specification.
What would you like to be added:
Object.prototype.hasOwnProperty
is used many times throughout the codebase. It is more efficient to cache the lookup (i.e. const has = Object.prototype.hasOwnProperty
) in a place like utils/
, and import it where it is needed.
Why is this needed:
It is more efficient. See Airbnb's style guide section on this topic.
The error log produced by plumadriver is somewhat messy. This needs to be cleaned up. A date should also be added everytime an error is logged.
PlumaOptions class which extends selenium's MutableCapabilities needs to be implemented
Description
PlumaDriver .getText() returns the innerHTML of the element instead of the textContent.
Steps/Code to Reproduce
public static void test(WebDriver driver)
{
driver.get("http://captive.apple.com");
WebElement element = driver.findElement(By.tagName("head"));
Assert.assertTrue(element.getText().equals("Success"));
}
Expected Results
Passing in a ChromeDriver instance and a PlumaDriver instance should both pass.
Actual Results
Passing in a ChromeDriver instance passes. Passing in a PlumaDriver instance fails, and the result of the call is <title>Success</title> instead of simply Success.
Versions
Is PlumaDriver versioned yet?
GitHub in reporting a critical severity warning for the lodash
dependency. Use npm audit
to update package versions.
What would you like to be added:
Delete All Cookies
Why is this needed:
It is part of the remaining set of endpoints responsible for cookie management.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.