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

Initial commit #23

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions mail-in-ballot-application-status-extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
26 changes: 26 additions & 0 deletions mail-in-ballot-application-status-extension/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// https://jestjs.io/docs/en/configuration.html

module.exports = {
// Automatically clear mock calls and instances between every test
clearMocks: true,

// The directory where Jest should output its coverage files
coverageDirectory: "coverage",

// An array of file extensions your modules use
moduleFileExtensions: [
'js',
'ts',
'json'
],

// The glob patterns Jest uses to detect test files
testMatch: [
'**/?(*.)+(test).ts'
],

// A map from regular expressions to paths to transformers
transform: {
'^.+\\.(ts)$': 'ts-jest'
}
};
15,733 changes: 15,733 additions & 0 deletions mail-in-ballot-application-status-extension/package-lock.json

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions mail-in-ballot-application-status-extension/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "mail-ballot-application-status-checker",
"version": "0.1.0",
"description": "Check the status of mail ballot applications.",
"scripts": {
"build": "webpack",
"lint": "eslint src/**/*.ts --fix",
"watch": "webpack --watch",
"ff": "web-ext --source-dir dist run",
"dev": "concurrently --kill-others \"npm run watch\" \"npm run reload\"",
"test": "npm run build && jest --verbose",
"test:unit": "jest --verbose --roots ./test/unit",
"jest": "jest"
},
"devDependencies": {
"@types/jest": "^26.0.14",
"@types/node": "^14.11.2",
"@types/selenium-webdriver": "^4.0.5",
"@typescript-eslint/eslint-plugin": "^4.2.0",
"@typescript-eslint/parser": "^4.2.0",
"clean-webpack-plugin": "^3.0.0",
"concurrently": "^5.0.1",
"copy-webpack-plugin": "^6.1.1",
"eslint": "^7.9.0",
"fx-runner": "^1.0.11",
"geckodriver": "^1.19.1",
"husky": "^4.3.0",
"jest": "^26.4.2",
"lint-staged": "^10.4.0",
"mz": "^2.7.0",
"prettier": "^2.1.2",
"selenium-webdriver": "^4.0.0-alpha.5",
"ts-jest": "^26.4.0",
"ts-loader": "^8.0.4",
"typescript": "^4.0.3",
"web-ext": "^5.1.0",
"webextension-polyfill": "^0.6.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"zip-webpack-plugin": "^3.0.0"
},
"lint-staged": {
"*.ts": [
"eslint 'src/**/*.ts' --fix",
"git add"
],
"*.{js,ts,json,css,md,html}": [
"prettier --write",
"git add"
]
},
"dependencies": {
"@types/firefox-webext-browser": "^78.0.1"
}
}
59 changes: 59 additions & 0 deletions mail-in-ballot-application-status-extension/src/background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const ballotStatusTrackerUrl =
'https://www.pavoterservices.pa.gov/Pages/BallotTracking.aspx';
let index;

const voters = [
['Ignore this placeholder.', 'Select Philadelphia in the dropdown.', '01/01/1900'],

];

browser.runtime.onInstalled.addListener(async () => {
console.log('onInstall()');

// Set the index to zero on install.
await browser.storage.local.set({ 'index': 0 });
});

browser.webNavigation.onCompleted.addListener(async (details) => {
console.log('Ballot status tracker page loaded.');
const tabId = details.tabId;

// Load current index from storage. This is required in case the extension
// is stopped/started.
const results = await browser.storage.local.get('index');
index = results['index'];
console.log('index = ', index);

if (index >= voters.length) {
browser.tabs.sendMessage(tabId, ['All', 'Done!', '']);
return;
}

// Load the correct voter to look up next.
const voter = voters[index];
console.log('Voter: ', JSON.stringify(voter));

// Send the voter data to the content script.
browser.tabs.sendMessage(tabId, voter);

// Update and save the index.
await browser.storage.local.set({ 'index': ++index });
}, {
url: [
{ urlEquals: ballotStatusTrackerUrl }
]
});

browser.runtime.onMessage.addListener(async (results) => {
const voter = voters[index - 2];

console.log('===== Results received =====');
console.log('Voter: ', JSON.stringify(voter));
console.log('Results: ', JSON.stringify(results));
console.log('==========');

const voterKey = voter.join('_');
await browser.storage.local.set({
[voterKey]: results
});
});
56 changes: 56 additions & 0 deletions mail-in-ballot-application-status-extension/src/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const firstNameId = '#ctl00_ContentPlaceHolder1_FirstNameText';
const lastNameId = '#ctl00_ContentPlaceHolder1_LastNameText';
const dobId = '#ctl00_ContentPlaceHolder1_DateOfBirthText';
const formId = '#aspnetForm';
const resultTableCells =
'#ctl00_ContentPlaceHolder1_ResultPanel table tr+tr+tr td';

function insertVoterData(voterData) {
const lastName = voterData[0];
const firstName = voterData[1];
const dob = voterData[2];

console.log('Entering voter: ', JSON.stringify(voterData));

const firstNameInput = document.querySelector(firstNameId);
(firstNameInput as HTMLInputElement).value = firstName;

const lastNameInput = document.querySelector(lastNameId);
(lastNameInput as HTMLInputElement).value = lastName;

const dobNameInput = document.querySelector(dobId);
(dobNameInput as HTMLInputElement).value = dob;
}

function getResults() {
let results: string[] = [];
const tableCells = document.querySelectorAll(resultTableCells);

if (tableCells.length > 0) {
for (let i = 0; i < tableCells.length; i++) {
const cell = tableCells[i];
let cellText = (cell as HTMLTableCellElement).textContent || '';
cellText = cellText.trim();
results.push(cellText);
}
browser.runtime.sendMessage(results);
}
}

// window.addEventListener('DOMContentLoaded', (event) => {
// console.log('DOM fully loaded and parsed');
// });

browser.runtime.onMessage.addListener((msg) => {
console.log('Received message: ', JSON.stringify(msg));
// const type = msg.type;
// const payload = msg.payload;

// if (type === 'voterData') {
// insertVoterData(payload);
// } else if (type === 'getResults') {
// getResults();
// }
insertVoterData(msg);
getResults();
});
18 changes: 18 additions & 0 deletions mail-in-ballot-application-status-extension/src/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "mail-in ballot application status checker",
"description": "",
"version": "0.1.0",
"manifest_version": 2,
"background": {
"scripts": ["browser-polyfill.js", "background.js"]
},
"content_scripts": [
{
"matches": [
"https://www.pavoterservices.pa.gov/Pages/BallotTracking.aspx"
],
"js": ["browser-polyfill.js", "content.js"]
}
],
"permissions": ["webNavigation", "storage", "unlimitedStorage"]
}
16 changes: 16 additions & 0 deletions mail-in-ballot-application-status-extension/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"lib": [
"ESNext",
"DOM",
"WebWorker"
],
"strictNullChecks": true,
"module": "commonjs",
"target": "ES2017",
"typeRoots": [
"node_modules/@types/",
"@types/"
]
}
}
64 changes: 64 additions & 0 deletions mail-in-ballot-application-status-extension/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ZipPlugin = require("zip-webpack-plugin");

const BUILD_PATH = path.resolve(__dirname, "dist");
const NAME = "status-checker";

module.exports = [
{
entry: {
background: "./src/background.ts",
content: "./src/content.ts",
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
options: { onlyCompileBundledFiles: true },
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".ts", ".js"],
},
output: {
filename: "[name].js",
sourceMapFilename: "[name].js.map",
path: BUILD_PATH,
},
devtool: "source-map",
mode: "none",
plugins: [
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{
// Copy webextension-pollyfill and its source map to
// ./${BUILD_PATH}. See docs for details on this setup:
// https://github.com/mozilla/webextension-polyfill/tree/faa22a4df1bc0bbaf2a6c093352d8df8b33b9b92#usage-with-webpack-without-bundling.
// The webextension-pollyfill provides the global namespace
// `browser`, which allows the extension to run in Chrome and
// Brave.
from:
"node_modules/webextension-polyfill/dist/browser-polyfill.js*",
flatten: true,
},
{
from: "./src/manifest.json",
},
],
}),
new ZipPlugin({
filename: `${NAME}`,
extension: "xpi",
}),
],
node: {
fs: "empty",
},
},
];