CyberChef/tests/browser/00_nightwatch.js

334 lines
10 KiB
JavaScript
Raw Normal View History

/**
2018-12-30 00:26:28 +00:00
* Tests to ensure that the app loads correctly in a reasonable time and that operations can be run.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
2023-03-06 14:53:20 +00:00
const utils = require("./browserUtils.js");
module.exports = {
2024-02-24 22:59:51 -05:00
before: (browser) => {
browser.resizeWindow(1280, 800).url(browser.launchUrl);
},
2024-02-24 22:59:51 -05:00
"Loading screen": (browser) => {
// Check that the loading screen appears and then disappears within a reasonable time
browser
.waitForElementVisible("#preloader", 300)
.waitForElementNotPresent("#preloader", 10000);
},
2024-02-24 22:59:51 -05:00
"App loaded": (browser) => {
browser.useCss();
// Check that various important elements are loaded
browser.expect.element("#operations").to.be.visible;
browser.expect.element("#recipe").to.be.visible;
browser.expect.element("#input").to.be.present;
browser.expect.element("#output").to.be.present;
browser.expect.element(".op-list").to.be.present;
browser.expect.element("#rec-list").to.be.visible;
browser.expect.element("#controls").to.be.visible;
browser.expect.element("#input-text").to.be.visible;
browser.expect.element("#output-text").to.be.visible;
},
2024-02-24 22:59:51 -05:00
"Operations loaded": (browser) => {
browser.useXpath();
2018-12-30 00:26:28 +00:00
// Check that an operation in every category has been populated
2024-02-24 22:59:51 -05:00
browser.expect.element(
"//li[contains(@class, 'operation') and text()='To Base64']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='To Binary']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='AES Decrypt']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='PEM to Hex']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Power Set']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Parse IP range']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Remove Diacritics']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Sort']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='To UNIX Timestamp']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Extract dates']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Gzip']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Keccak']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='JSON Beautify']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Detect File Type']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Play Media']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Disassemble x86']",
).to.be.present;
browser.expect.element(
"//li[contains(@class, 'operation') and text()='Register']",
).to.be.present;
},
2024-02-24 22:59:51 -05:00
"Recipe can be run": (browser) => {
const toHex = "//li[contains(@class, 'operation') and text()='To Hex']";
const op = "#rec-list .operation .op-title";
// Check that operation is visible
2024-02-24 22:59:51 -05:00
browser.useXpath().expect.element(toHex).to.be.visible;
// Add it to the recipe by double clicking
browser
.useXpath()
.moveToElement(toHex, 10, 10)
.useCss()
2018-12-30 00:47:10 +00:00
.waitForElementVisible(".popover-body", 1000)
2022-03-28 15:42:11 +01:00
.doubleClick("xpath", toHex);
// Confirm that it has been added to the recipe
browser
.useCss()
.waitForElementVisible(op, 100)
2024-02-24 22:59:51 -05:00
.expect.element(op)
.text.to.contain("To Hex");
// Enter input
browser
.useCss()
.sendKeys("#input-text .cm-content", "Don't Panic.")
.pause(1000)
.click("#bake");
// Check output
browser
.useCss()
.waitForElementNotVisible("#stale-indicator", 1000)
2024-02-24 22:59:51 -05:00
.expect.element("#output-text .cm-content")
.text.that.equals("44 6f 6e 27 74 20 50 61 6e 69 63 2e");
// Clear recipe
browser
.useCss()
.moveToElement(op, 10, 10)
2018-12-30 00:47:10 +00:00
.waitForElementNotPresent(".popover-body", 1000)
.click("#clr-recipe")
.waitForElementNotPresent(op);
},
2024-02-24 22:59:51 -05:00
"Test every module": (browser) => {
browser.useCss();
// BSON
2024-02-24 22:59:51 -05:00
loadOp("BSON deserialise", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Charts
2024-02-24 22:59:51 -05:00
loadOp("Entropy", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Ciphers
2024-02-24 22:59:51 -05:00
loadOp("AES Encrypt", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Code
2024-02-24 22:59:51 -05:00
loadOp("XPath expression", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Compression
2024-02-24 22:59:51 -05:00
loadOp("Gzip", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Crypto
2024-02-24 22:59:51 -05:00
loadOp("MD5", browser).waitForElementNotVisible("#output-loader", 5000);
// Default
2024-02-24 22:59:51 -05:00
loadOp("Fork", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Diff
2024-02-24 22:59:51 -05:00
loadOp("Diff", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Encodings
2024-02-24 22:59:51 -05:00
loadOp("Encode text", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Hashing
2024-02-24 22:59:51 -05:00
loadOp("Streebog", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Image
2024-02-24 22:59:51 -05:00
loadOp("Extract EXIF", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// PGP
2024-02-24 22:59:51 -05:00
loadOp("PGP Encrypt", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// PublicKey
2024-02-24 22:59:51 -05:00
loadOp("Hex to PEM", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Regex
2024-02-24 22:59:51 -05:00
loadOp("Strings", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// Shellcode
2024-02-24 22:59:51 -05:00
loadOp("Disassemble x86", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// URL
2024-02-24 22:59:51 -05:00
loadOp("URL Encode", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// UserAgent
2024-02-24 22:59:51 -05:00
loadOp("Parse User Agent", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
// YARA
2024-02-24 22:59:51 -05:00
loadOp("YARA Rules", browser).waitForElementNotVisible(
"#output-loader",
5000,
);
browser.click("#clr-recipe");
},
2024-02-24 22:59:51 -05:00
"Move around the UI": (browser) => {
const otherCat =
"//a[contains(@class, 'category-title') and contains(@data-target, '#catOther')]",
genUUID =
"//li[contains(@class, 'operation') and text()='Generate UUID']";
browser.useXpath();
// Scroll to a lower category
2024-02-24 22:59:51 -05:00
browser.getLocationInView(otherCat).expect.element(otherCat).to.be
.visible;
// Open category
2024-02-24 22:59:51 -05:00
browser.click(otherCat).expect.element(genUUID).to.be.visible;
2019-08-30 15:30:30 +01:00
// Add op to recipe
/* mouseButtonUp drops wherever the actual cursor is, not necessarily in the right place,
so we can't test Sortable.js properly using Nightwatch. html-dnd doesn't work either.
Instead of relying on drag and drop, we double click on the op to load it. */
browser
.getLocationInView(genUUID)
.moveToElement(genUUID, 10, 10)
2022-03-28 15:42:11 +01:00
.doubleClick("xpath", genUUID)
.useCss()
.waitForElementVisible(".operation .op-title", 1000)
.waitForElementNotVisible("#stale-indicator", 1000)
2024-02-24 22:59:51 -05:00
.expect.element("#output-text .cm-content")
.text.which.matches(/[\da-f-]{36}/);
browser.click("#clr-recipe");
},
2024-02-24 22:59:51 -05:00
Search: (browser) => {
// Search for an op
browser
.useCss()
.clearValue("#search")
.setValue("#search", "md5")
.useXpath()
2024-02-24 22:59:51 -05:00
.waitForElementVisible(
"//ul[@id='search-results']//b[text()='MD5']",
1000,
);
},
2024-02-24 22:59:51 -05:00
"Alert bar": (browser) => {
2023-03-06 14:53:20 +00:00
// Bake nothing to create an empty output which can be copied
utils.clear(browser);
utils.bake(browser);
// Alert bar shows and contains correct content
browser
.click("#copy-output")
.waitForElementVisible("#snackbar-container")
.waitForElementVisible("#snackbar-container .snackbar-content")
2024-02-24 22:59:51 -05:00
.expect.element("#snackbar-container .snackbar-content")
.text.to.equal("Copied raw output successfully.");
2023-03-06 14:53:20 +00:00
// Alert bar disappears after the correct amount of time
// Should disappear after 2000ms
browser
2024-02-24 22:59:51 -05:00
.waitForElementNotPresent(
"#snackbar-container .snackbar-content",
2500,
)
2023-03-06 14:53:20 +00:00
.waitForElementNotVisible("#snackbar-container");
},
2024-02-24 22:59:51 -05:00
after: (browser) => {
browser.end();
2024-02-24 22:59:51 -05:00
},
};
/**
* Clears the current recipe and loads a new operation.
*
* @param {string} opName
* @param {Browser} browser
*/
function loadOp(opName, browser) {
return browser
.useCss()
.click("#clr-recipe")
.urlHash("op=" + opName);
}