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

Enrich valueChanged event to include source #43

Merged
merged 8 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
node-version: [20.x]
ci-test: ["web", "integration"]
steps:
- uses: actions/checkout@v2
Expand All @@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
node-version: [20.x]
steps:
- uses: actions/checkout@v2
- name: Formatting tests ${{ matrix.node-version }}
Expand Down
6,351 changes: 3,952 additions & 2,399 deletions package-lock.json

Large diffs are not rendered by default.

27 changes: 14 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,31 @@
"puppeteer_skip_chromium_download": true
},
"dependencies": {
"eventemitter3": "^5.0.0",
"eventemitter3": "^5.0.1",
"is-visible": "^2.2.0"
},
"devDependencies": {
"@babel/core": "^7.21.4",
"@babel/preset-env": "^7.21.4",
"babel-loader": "^9.1.2",
"chai": "^4.3.7",
"concurrently": "^8.0.1",
"@babel/core": "^7.24.3",
"@babel/preset-env": "^7.24.3",
"@types/node": "^20.11.30",
"babel-loader": "^9.1.3",
"chai": "^4.4.1",
"concurrently": "^8.2.2",
"husky": "^4.3.8",
"lint-staged": "^13.2.2",
"mocha": "^10.2.0",
"mochify": "^9.2.0",
"npm-run-all": "^4.1.3",
"prettier": "^2.8.8",
"puppeteer": "^19.11.1",
"puppeteer": "^22.6.0",
"resolve-typescript-plugin": "^2.0.1",
"rimraf": "^5.0.0",
"serve": "^14.2.0",
"rimraf": "^5.0.5",
"serve": "^14.2.1",
"sinon": "^15.0.4",
"sleep-promise": "^9.1.0",
"ts-loader": "^9.4.2",
"typescript": "^5.0.4",
"webpack": "^5.81.0",
"webpack-cli": "^5.0.2"
"ts-loader": "^9.5.1",
"typescript": "^5.4.2",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
}
}
14 changes: 14 additions & 0 deletions source/LocustInputEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type InputEventTrigger = "keypress" | "fill";

export class LocustInputEvent extends Event {
private _source: InputEventTrigger;

constructor(source: InputEventTrigger, type: string, eventInitDict?: EventInit) {
super(type, eventInitDict);
this._source = source;
}

get source(): InputEventTrigger {
return this._source;
}
}
13 changes: 8 additions & 5 deletions source/LoginTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import EventEmitter from "eventemitter3";
import { getSharedObserver as getUnloadObserver } from "./UnloadObserver.js";
import { setInputValue } from "./inputs.js";
import { LoginTargetFeature } from "./types.js";
import { LocustInputEvent } from "./LocustInputEvent.js";

interface ChangeListener {
input: HTMLElement;
Expand All @@ -11,7 +12,7 @@ interface ChangeListener {

interface LoginTargetEvents {
formSubmitted: (event: { source: "form" | "submitButton"; }) => void;
valueChanged: (event: { type: LoginTargetFeature; value: string; }) => void;
valueChanged: (event: { source: "keypress" | "fill", type: LoginTargetFeature; value: string; }) => void;
}

export const FORCE_SUBMIT_DELAY = 7500;
Expand Down Expand Up @@ -260,21 +261,23 @@ export class LoginTarget extends EventEmitter<LoginTargetEvents> {
input.removeEventListener(eventListenerName, listener, false);
}
// Emit a value change event
let handleEvent = NOOP;
let handleEvent: (evt?: Event) => void = NOOP;
if (type === "submit" || type === "form") {
// Listener function for the submission of the form
const source = type === "form" ? "form" : "submitButton";
handleEvent = () => this.emit("formSubmitted", { source });
} else {
const emit = (value: string) => {
const emit = (value: string, source: "keypress" | "fill") => {
this.emit("valueChanged", {
source,
type,
value
});
};
// Listener function for the input element
handleEvent = function () {
emit(this.value);
handleEvent = function (evt: Event) {
const source = evt instanceof LocustInputEvent ? evt.source : "keypress";
emit(this.value, source);
};
}
// Store the listener information
Expand Down
5 changes: 3 additions & 2 deletions source/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SUBMIT_BUTTON_QUERIES,
USERNAME_QUERIES
} from "./inputPatterns.js";
import { LocustInputEvent } from "./LocustInputEvent.js";

export interface FetchedForm {
form: HTMLFormElement;
Expand Down Expand Up @@ -147,9 +148,9 @@ function isInput(el: Element): boolean {

export function setInputValue(input: HTMLInputElement, value: string): void {
nativeInputValueSetter.call(input, value);
const inputEvent = new Event("input", { bubbles: true });
const inputEvent = new LocustInputEvent("fill", "input", { bubbles: true });
input.dispatchEvent(inputEvent);
const changeEvent = new Event("change", { bubbles: true });
const changeEvent = new LocustInputEvent("fill", "change", { bubbles: true });
input.dispatchEvent(changeEvent);
}

Expand Down
7 changes: 6 additions & 1 deletion test-integration/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ const TESTS = require("./test-forms.json");
const LOCUST_PATH = path.resolve(__dirname, "../dist/index.js");

async function initialiseBrowser() {
const browser = await puppeteer.launch();
const browser = await puppeteer.launch({ headless: "new" });
const page = await browser.newPage();
await page.setViewport({
width: 1024,
height: 768,
deviceScaleFactor: 1
});
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109) Gecko/20100101 Firefox/112.0");
await page.setBypassCSP(true);
await page.evaluateOnNewDocument(() => {
Expand Down
23 changes: 12 additions & 11 deletions test-integration/test-forms.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
{
"name": "Meetabit",
"url": "https://meetabit.com/users/sign_in",
"expectedFields": {
"username": "input#user_email",
"password": "input#user_password"
}
},
{
"name": "OTP Test @ stackblitz",
"url": "https://js-flbjc3.stackblitz.io",
Expand Down Expand Up @@ -39,18 +47,11 @@
}
},
{
"name": "Reddit",
"url": "https://www.reddit.com/login",
"name": "Fill.dev",
"url": "https://fill.dev/form/login-simple",
"expectedFields": {
"username": "#loginUsername",
"password": "#loginPassword"
}
},
{
"name": "Amazon",
"url": "https://www.amazon.com/ap/signin?_encoding=UTF8&ignoreAuthState=1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2F%3Fref_%3Dnav_custrec_signin&switch_account=",
"expectedFields": {
"username": "form[name=signIn] input#ap_email"
"username": "input#username",
"password": "input#password"
}
},
{
Expand Down
26 changes: 26 additions & 0 deletions test/LoginTarget.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ describe("LoginTarget", function () {
expect(currentValue).to.equal("user5644");
});

it("specifies event source as 'fill' when set using the setter method", function () {
let source = "";
this.target.usernameField = document.createElement("input");
this.target.on("valueChanged", (info) => {
if (info.type === "username") {
source = info.source;
}
});
setInputValue(this.target.usernameField, "user5644");
expect(source).to.equal("fill");
});

it("specifies event source as 'keypress' when set updating the input", function () {
let source = "";
this.target.usernameField = document.createElement("input");
this.target.on("valueChanged", (info) => {
if (info.type === "username") {
source = info.source;
}
});
this.target.usernameField.value = "user5655";
this.target.usernameField.dispatchEvent(new Event("input"));
this.target.usernameField.dispatchEvent(new Event("change"));
expect(source).to.equal("keypress");
});

it("fires events when the submit button is clicked", function () {
let formSubmitted = 0;
this.target.on("formSubmitted", (info) => {
Expand Down
Loading