mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-07 06:57:12 -04:00
add local storage availability check, prep for code review
This commit is contained in:
parent
5b25b74775
commit
02a4dd5bd3
9 changed files with 39 additions and 261 deletions
|
@ -68,8 +68,8 @@ class HTMLOperation {
|
|||
html += "<i class='material-icons check-icon op-icon'>check</i>";
|
||||
}
|
||||
|
||||
// check if local storage has favourites at all
|
||||
const isFavourite = localStorage.favourites?.includes(this.name)
|
||||
// check if local storage is available *and* has favourites at all ( otherwise we use the default favs )
|
||||
const isFavourite = this.app.isLocalStorageAvailable() && localStorage.favourites?.includes(this.name);
|
||||
|
||||
if (window.innerWidth < this.app.breakpoint) {
|
||||
html += `<i title="${this.name}" class='material-icons icon-add-favourite star-icon op-icon ${isFavourite ? "fav-op" : ""}'>
|
||||
|
|
1
tests/browser/mobile-device/TODO.md
Normal file
1
tests/browser/mobile-device/TODO.md
Normal file
|
@ -0,0 +1 @@
|
|||
actual mobile device tests go here
|
|
@ -1,9 +1,17 @@
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
const utils = require("./browserUtils.js");
|
||||
|
||||
module.exports = {
|
||||
before: browser => {
|
||||
browser
|
||||
.resizeWindow(412, 915) // Galaxy S20 Ultra-ish size
|
||||
.resizeWindow(1280, 800)
|
||||
.url(browser.launchUrl);
|
||||
},
|
||||
|
||||
|
@ -11,33 +19,25 @@ module.exports = {
|
|||
// Check that the loading screen appears and then disappears within a reasonable time
|
||||
browser
|
||||
.waitForElementVisible("#preloader", 300)
|
||||
.waitForElementNotPresent("#preloader", 30000);
|
||||
.waitForElementNotPresent("#preloader", 10000);
|
||||
},
|
||||
|
||||
"App loaded": browser => {
|
||||
browser.useCss();
|
||||
// Check that various important elements are loaded
|
||||
browser.expect.element("#operations").to.be.visible;
|
||||
browser.expect.element("#search").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;
|
||||
},
|
||||
|
||||
// "Operations dropdown loaded": browser => {
|
||||
// browser
|
||||
// .useCss()
|
||||
// .click("#search")
|
||||
// .expect.element("#operations-dropdown").to.be.visible
|
||||
// .expect.element("#categories").to.be.visible
|
||||
// .expect.element(".op-list").to.be.present;
|
||||
// },
|
||||
|
||||
"Operations loaded": browser => {
|
||||
browser.useXpath();
|
||||
// Check that an operation in every category has been populated
|
||||
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;
|
|
@ -1,3 +1,12 @@
|
|||
/**
|
||||
* Tests for input and output of various types to ensure the editors work as expected
|
||||
* and retain data integrity, especially when it comes to special characters.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
// import {
|
||||
// clear,
|
||||
// utils.setInput,
|
|
@ -1,3 +1,18 @@
|
|||
/**
|
||||
* Tests for operations.
|
||||
* The primary purpose for these test is to ensure that the operations
|
||||
* output something vaguely expected (i.e. they aren't completely broken
|
||||
* after a dependency update or changes to the UI), rather than to confirm
|
||||
* that this output is actually accurate. Accuracy of output and testing
|
||||
* of edge cases should be carried out in the operations test suite found
|
||||
* in /tests/operations as this is much faster and easier to configure
|
||||
* than the UI tests found here.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
const utils = require("./browserUtils.js");
|
||||
|
||||
module.exports = {
|
|
@ -1,247 +0,0 @@
|
|||
/**
|
||||
* Utility functions for browser tests.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/** @function
|
||||
* Clears the recipe and input
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
*/
|
||||
function clear(browser) {
|
||||
browser
|
||||
.useCss()
|
||||
.click("#clr-recipe")
|
||||
.click("#clr-io")
|
||||
.waitForElementNotPresent("#rec-list li.operation")
|
||||
.expect.element("#input-text .cm-content").text.that.equals("");
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Sets the input to the desired string
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} input - The text to populate the input with
|
||||
* @param {boolean} [type=true] - Whether to type the characters in by using sendKeys,
|
||||
* or to set the value of the editor directly (useful for special characters)
|
||||
*/
|
||||
function setInput(browser, input, type=true) {
|
||||
clear(browser);
|
||||
if (type) {
|
||||
browser
|
||||
.useCss()
|
||||
.sendKeys("#input-text .cm-content", input)
|
||||
.pause(100);
|
||||
} else {
|
||||
browser.execute(text => {
|
||||
window.app.setInput(text);
|
||||
}, [input]);
|
||||
}
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Triggers a bake
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
*/
|
||||
function bake(browser) {
|
||||
browser
|
||||
.click("#bake")
|
||||
.waitForElementNotVisible("#stale-indicator", 5000)
|
||||
.waitForElementNotVisible("#output-loader", 5000);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Sets the character encoding in the input or output
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} io - Either "input" or "output"
|
||||
* @param {string} enc - The encoding to be set
|
||||
*/
|
||||
function setChrEnc(browser, io, enc) {
|
||||
io = `#${io}-text`;
|
||||
browser
|
||||
.useCss()
|
||||
.click(io + " .chr-enc-value")
|
||||
.waitForElementVisible(io + " .chr-enc-select .cm-status-bar-select-scroll")
|
||||
.click("link text", enc)
|
||||
.waitForElementNotVisible(io + " .chr-enc-select .cm-status-bar-select-scroll")
|
||||
.expect.element(io + " .chr-enc-value").text.that.equals(enc);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Sets the end of line sequence in the input or output
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} io - Either "input" or "output"
|
||||
* @param {string} eol - The sequence to set
|
||||
*/
|
||||
function setEOLSeq(browser, io, eol) {
|
||||
io = `#${io}-text`;
|
||||
browser
|
||||
.useCss()
|
||||
.click(io + " .eol-value")
|
||||
.waitForElementVisible(io + " .eol-select .cm-status-bar-select-content")
|
||||
.click(`${io} .cm-status-bar-select-content a[data-val=${eol}]`)
|
||||
.waitForElementNotVisible(io + " .eol-select .cm-status-bar-select-content")
|
||||
.expect.element(io + " .eol-value").text.that.equals(eol);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Copies whatever is currently selected
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
*/
|
||||
function copy(browser) {
|
||||
browser.perform(function() {
|
||||
const actions = this.actions({async: true});
|
||||
|
||||
// Ctrl + Ins used as this works on Windows, Linux and Mac
|
||||
return actions
|
||||
.keyDown(browser.Keys.CONTROL)
|
||||
.keyDown(browser.Keys.INSERT)
|
||||
.keyUp(browser.Keys.INSERT)
|
||||
.keyUp(browser.Keys.CONTROL);
|
||||
});
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Pastes into the target element
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} el - Target element selector
|
||||
*/
|
||||
function paste(browser, el) {
|
||||
browser
|
||||
.click(el)
|
||||
.perform(function() {
|
||||
const actions = this.actions({async: true});
|
||||
|
||||
// Shift + Ins used as this works on Windows, Linux and Mac
|
||||
return actions
|
||||
.keyDown(browser.Keys.SHIFT)
|
||||
.keyDown(browser.Keys.INSERT)
|
||||
.keyUp(browser.Keys.INSERT)
|
||||
.keyUp(browser.Keys.SHIFT);
|
||||
})
|
||||
.pause(100);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Loads a recipe and input
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string|Array<string>} opName - name of operation to be loaded, array for multiple ops
|
||||
* @param {string} input - input text for test
|
||||
* @param {Array<string>|Array<Array<string>>} args - arguments, nested if multiple ops
|
||||
*/
|
||||
function loadRecipe(browser, opName, input, args) {
|
||||
let recipeConfig;
|
||||
|
||||
if (typeof(opName) === "string") {
|
||||
recipeConfig = JSON.stringify([{
|
||||
"op": opName,
|
||||
"args": args
|
||||
}]);
|
||||
} else if (opName instanceof Array) {
|
||||
recipeConfig = JSON.stringify(
|
||||
opName.map((op, i) => {
|
||||
return {
|
||||
op: op,
|
||||
args: args.length ? args[i] : []
|
||||
};
|
||||
})
|
||||
);
|
||||
} else {
|
||||
throw new Error("Invalid operation type. Must be string or array of strings. Received: " + typeof(opName));
|
||||
}
|
||||
|
||||
clear(browser);
|
||||
setInput(browser, input, false);
|
||||
browser
|
||||
.urlHash("recipe=" + recipeConfig)
|
||||
.waitForElementPresent("#rec-list li.operation");
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Tests whether the output matches a given value
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string|RegExp} expected - The expected output value
|
||||
*/
|
||||
function expectOutput(browser, expected) {
|
||||
browser.execute(expected => {
|
||||
const output = window.app.manager.output.outputEditorView.state.doc.toString();
|
||||
if (expected instanceof RegExp) {
|
||||
return expected.test(output);
|
||||
} else {
|
||||
return expected === output;
|
||||
}
|
||||
}, [expected]);
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Uploads a file using the #open-file input
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} filename - A path to a file in the samples directory
|
||||
*/
|
||||
function uploadFile(browser, filename) {
|
||||
const filepath = require("path").resolve(__dirname + "/../samples/" + filename);
|
||||
|
||||
// The file input cannot be interacted with by nightwatch while it is hidden,
|
||||
// so we temporarily expose it for the purposes of this test.
|
||||
browser.execute(() => {
|
||||
document.getElementById("open-file").style.display = "block";
|
||||
});
|
||||
browser
|
||||
.pause(100)
|
||||
.setValue("#open-file", filepath)
|
||||
.pause(100);
|
||||
browser.execute(() => {
|
||||
document.getElementById("open-file").style.display = "none";
|
||||
});
|
||||
browser.waitForElementVisible("#input-text .cm-file-details");
|
||||
}
|
||||
|
||||
/** @function
|
||||
* Uploads a folder using the #open-folder input
|
||||
*
|
||||
* @param {Browser} browser - Nightwatch client
|
||||
* @param {string} foldername - A path to a folder in the samples directory
|
||||
*/
|
||||
function uploadFolder(browser, foldername) {
|
||||
const folderpath = require("path").resolve(__dirname + "/../samples/" + foldername);
|
||||
|
||||
// The folder input cannot be interacted with by nightwatch while it is hidden,
|
||||
// so we temporarily expose it for the purposes of this test.
|
||||
browser.execute(() => {
|
||||
document.getElementById("open-folder").style.display = "block";
|
||||
});
|
||||
browser
|
||||
.pause(100)
|
||||
.setValue("#open-folder", folderpath)
|
||||
.pause(500);
|
||||
browser.execute(() => {
|
||||
document.getElementById("open-folder").style.display = "none";
|
||||
});
|
||||
browser.waitForElementVisible("#input-text .cm-file-details");
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
clear: clear,
|
||||
setInput: setInput,
|
||||
bake: bake,
|
||||
setChrEnc: setChrEnc,
|
||||
setEOLSeq: setEOLSeq,
|
||||
copy: copy,
|
||||
paste: paste,
|
||||
loadRecipe: loadRecipe,
|
||||
expectOutput: expectOutput,
|
||||
uploadFile: uploadFile,
|
||||
uploadFolder: uploadFolder
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue