Skip to content

Commit

Permalink
feat(*): finishing touches
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickersoft committed Jul 4, 2023
1 parent 4c74f6b commit 0b4413c
Show file tree
Hide file tree
Showing 13 changed files with 422 additions and 697 deletions.
24 changes: 21 additions & 3 deletions .oarc.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
{
"show": true,
"filterLinks": "/read",
"$schema": "./oa.schema.json",
"url": "http://app-dev.linguistic.io:9000/read",
"show": false,
"cookies": [
{
"name": "session",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2ODg0MzYyMjMsImV4cCI6MTY4ODQzODAyMywiYXVkIjoiaHR0cHM6Ly9saW5ndWlzdGljLmlvIiwiaXNzIjoiaHR0cHM6Ly9saW5ndWlzdGljLmlvIiwic3ViIjoiMTgwIn0.RKoH9_1j_A64xiSAqacydwmbKevVJE38_xYAsT55YS8%3AeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2ODg0MzYyMjMsImV4cCI6MTY5MTExNDYyMywiYXVkIjoiaHR0cHM6Ly9saW5ndWlzdGljLmlvIiwiaXNzIjoiaHR0cHM6Ly9saW5ndWlzdGljLmlvIiwic3ViIjoiMTgwIiwianRpIjoiMjMifQ.LNR3P9rWhfwBIPW7d0JPDGQ7Gc41dguBBT5dIt9xyYQ.NEwrRX9bteOfg5Tr3XvHEVZXRw32vXGXOUc1SMMav%2Bg"
}
]
],
"headers": {
"Key": "Value"
},
"targets": {
"links": {
"enabled": true
},
"buttons": {
"enabled": false
},
"typing": {
"enabled": true
},
"inputs": {
"enabled": false
}
}
}
595 changes: 50 additions & 545 deletions deno.lock

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { getSetCookies } from "https://deno.land/std@0.192.0/http/cookie.ts";

export { deepMerge } from "https://deno.land/std@0.192.0/collections/deep_merge.ts";

export {
default as puppeteer,
type ElementHandle,
Expand Down Expand Up @@ -32,13 +34,8 @@ export {
export * as stdColors from "https://deno.land/std@0.192.0/fmt/colors.ts";

export { colors } from "https://deno.land/x/cliffy@v1.0.0-rc.1/ansi/colors.ts";

export {
type BackgroundColorName,
backgroundColorNames,
Chalk,
type ChalkInstance,
} from "npm:chalk@^5";
export { Table } from "https://deno.land/x/cliffy@v1.0.0-rc.1/table/table.ts";
export { Row } from "https://deno.land/x/cliffy@v1.0.0-rc.1/table/row.ts";

export { default as ms } from "npm:ms@^2";

Expand Down
98 changes: 98 additions & 0 deletions oa.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Generated schema for Root",
"type": "object",
"properties": {
"url": {
"type": "string"
},
"show": {
"type": "boolean"
},
"cookies": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"name",
"value"
]
}
},
"headers": {
"type": "object",
"properties": {
"Key": {
"type": "string"
}
},
"required": [
"Key"
]
},
"targets": {
"type": "object",
"properties": {
"links": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"filter": {
"type": "string"
}
},
"required": [
"enabled"
]
},
"buttons": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
]
},
"typing": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
]
},
"inputs": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"required": [
"enabled"
]
}
},
"required": []
}
},
"required": [
"url"
]
}
3 changes: 0 additions & 3 deletions src/chalk.ts

This file was deleted.

137 changes: 55 additions & 82 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import {
type ArgumentValue,
type BackgroundColorName,
backgroundColorNames,
ArgumentValue,
colors,
Command,
getSetCookies,
objectify,
Protocol,
range,
shake,
string,
ValidationError,
} from "../deps.ts";
import { loadConfig } from "./config.ts";
import { defaultConfig, loadConfig } from "./config.ts";
import { BG_COLORS } from "./constants.ts";

import { MonkeyConfig, monkeyTest } from "./monkey.ts";
import { monkeyTest } from "./monkey.ts";
import { randomSubset } from "./random.ts";
import { ColorMethods } from "./types.ts";
import { kvToMap, validateURL } from "./utils.ts";

function urlType({ value }: ArgumentValue): string {
if (string().url().safeParse(value).success === false) {
throw new ValidationError(
"Invalid URL. URLs must include a protocol and domain.",
);
}
export function urlType({ value }: ArgumentValue): string {
validateURL(value);
return value;
}

function kvType({ value }: ArgumentValue): string {
export function kvType({ value }: ArgumentValue): string {
if (value.split("=").length !== 2) {
throw new ValidationError(
"Invalid cookie. Must be of the format name=value.",
Expand All @@ -34,27 +29,19 @@ function kvType({ value }: ArgumentValue): string {
return value;
}

function kvToMap(kv: string[]) {
return objectify(
kv?.map((cookie) => cookie.split("=")) ?? [],
([key]) => key,
([_, value]) => value,
);
}

export const cli = await new Command()
.name("oa")
.description("A Deno-based monkey testing CLI.")
.version("v0.0.1")
.type("URL", urlType)
.type("KV", kvType)
.arguments("<url:URL>")
.arguments("[url:URL]")
.option("-n, --num <num:integer>", "Number of monkeys to dispatch.", {
default: 1,
default: defaultConfig.num,
})
.option("-s, --show", "Show the browser windows.")
.option("-d, --duration <duration:string>", "How long to run the test.", {
default: "10s",
default: defaultConfig.duration,
})
.option(
"-f, --filter-links <filter:string>",
Expand All @@ -65,6 +52,7 @@ export const cli = await new Command()
.option("-L, --skip-links", "Skip clicking links.")
.option("-I, --skip-inputs", "Skip filling inputs.")
.option("-T, --skip-typing", "Skip sending random keystrokes.")
.option("-D, --debug", "Whether to print additional debug information.")
.option(
"-c, --cookie <cookie:KV>",
"Cookie to pass to the browser. Can be used multiple times. Example: -c foo=bar -c baz=qux.",
Expand All @@ -80,69 +68,54 @@ export const cli = await new Command()
{ collect: true },
)
.action(
async (
{
cookie = [],
header = [],
configFile,
duration,
show,
num,
skipButtons,
skipInputs,
skipLinks,
skipTyping,
filterLinks,
},
url,
) => {
const loadedConfig = await loadConfig(configFile) ?? {};
async ({ cookie = [], header = [], debug, configFile, ...flags }, url) => {
const headers = kvToMap(header);

const config = {
duration: "10s",
show: false,
num: num ?? 1,
cookies: [],
headers: {},
...loadedConfig,
};
const cookies = getSetCookies(
new Headers(cookie.map((cookie) => ["set-cookie", cookie])),
) as Protocol.Network.CookieParam[];

const colors = randomSubset(backgroundColorNames, config.num);
const config = await loadConfig(configFile, {
...flags,
url,
headers,
cookies,
debug,
targets: {
...flags.skipButtons && { buttons: { enabled: false } },
...flags.skipInputs && { inputs: { enabled: false } },
...flags.skipLinks && { links: { enabled: false } },
...flags.skipTyping && { typing: { enabled: false } },
...flags.filterLinks &&
{
links: {
enabled: true,
filter: flags.filterLinks,
},
},
},
});

const cookies = [
...config.cookies,
...getSetCookies(
new Headers(cookie.map((cookie) => ["set-cookie", cookie])),
),
]
.map((cookie) => {
if (!cookie.domain) {
cookie.domain = new URL(url).hostname;
}
return cookie;
}) as Protocol.Network.CookieParam[];
if (debug) {
console.log(
`\n${colors.bold("Configuration:")}\n\n${
JSON.stringify(config, null, 2)
}\n`,
);
}

const headers = kvToMap(header);
const monkeyColors = randomSubset(
BG_COLORS,
config.num,
) as ColorMethods[];

await Promise.all(
Array.from(range(1, config.num)).map((num, idx) =>
monkeyTest({
...config,
...shake({
name: `Monkey ${num}`,
duration,
color: colors[idx] as BackgroundColorName,
url,
show,
headers,
cookies,
skipButtons,
skipLinks,
skipInputs,
skipTyping,
filterLinks,
}) as MonkeyConfig,
})
monkeyTest(
`Monkey ${num}`,
monkeyColors[idx],
config,
)
),
);

Expand Down
Loading

0 comments on commit 0b4413c

Please sign in to comment.