Last active
April 14, 2023 20:57
-
-
Save rynomad/b123f1698655bbc9c0c155c4485ba748 to your computer and use it in GitHub Desktop.
Jasmine TestRunner for ChatMonkey
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Jasmine Test Runner | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Run Jasmine tests on a page with GM.communicator | |
// @author You | |
// @match *://*/* | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.10.0/jasmine.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.10.0/jasmine-html.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.10.0/boot.min.js | |
// @require https://code.jquery.com/jquery-3.6.0.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.4/chai.min.js | |
// @grant GM.addStyle | |
// @grant GM.deleteValue | |
// @grant GM.getValue | |
// @grant GM.listValues | |
// @grant GM.setValue | |
// @grant GM.xmlHttpRequest | |
// @grant GM.notification | |
// @grant GM.openInTab | |
// @grant GM.getResourceUrl | |
// @grant GM.setClipboard | |
// @grant GM.info | |
// @grant GM.registerMenuCommand | |
// @grant GM.unregisterMenuCommand | |
// @grant GM.download | |
// @grant GM.getTab | |
// @grant GM.saveTab | |
// @grant GM.getTabs | |
// @grant GM.connect | |
// @grant GM.setIcon | |
// @grant GM.fetch | |
// @grant GM.communicator | |
// @grant. GM.gpt | |
// @grant unsafeWindow | |
// @inject-into content | |
// ==/UserScript== | |
(async function() { | |
'use strict'; | |
if (!unsafeWindow.location.hash) { | |
function clearJasmine(){ | |
$('.jasmine_html-reporter').remove() | |
requestIdleCallback(clearJasmine) | |
} | |
requestIdleCallback(clearJasmine) | |
return; | |
} | |
// Load Jasmine CSS | |
const jasmineCssSource = 'https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.10.0/jasmine.min.css'; | |
await new Promise((resolve, reject) => { | |
const link = document.createElement('link'); | |
link.href = jasmineCssSource; | |
link.rel = 'stylesheet'; | |
link.onload = resolve; | |
link.onerror = reject; | |
document.head.appendChild(link); | |
}); | |
// Extract @require URLs from the code string | |
function extractRequireUrls(code) { | |
const regex = /\/\/\s*@require\s+(https?:\/\/[^\s]+)/g; | |
const urls = []; | |
let match; | |
while ((match = regex.exec(code)) !== null) { | |
urls.push(match[1]); | |
} | |
return urls; | |
} | |
// Create a fullscreen modal for test results | |
// Load required scripts and create the Jasmine test runner | |
async function runCode(code, test) { | |
const requireUrls = extractRequireUrls(code); | |
for (const url of requireUrls) { | |
await new Promise((resolve, reject) => { | |
const script = document.createElement('script'); | |
script.src = url; | |
script.onload = resolve; | |
script.onerror = reject; | |
document.head.appendChild(script); | |
}); | |
} | |
if (code.startsWith('javascript:')){ | |
code = code.substring('javascript:'.length) | |
} | |
try { | |
// ... (same as before, without the `executeCode` and `executeTest` lines) | |
const executeCode = new Function('unsafeWindow', 'GM','$','jQuery', `const window = unsafeWindow; ${code}; return window;`)(unsafeWindow, GM, jQuery, jQuery); | |
if (!test){ | |
return { | |
success: true | |
} | |
} | |
console.log("JASMINE", jasmine, jasmine.expect) | |
const executeTest = new Function('window','jasmine','describe','it','$','jQuery','expect', | |
`${test}; | |
class CustomReporter { | |
constructor() { | |
this.finished = false; | |
this.result = null; | |
} | |
jasmineDone(result) { | |
this.finished = true; | |
this.result = result; | |
} | |
} | |
return (async () => { | |
const jasmineEnv = jasmine.getEnv(); | |
const customReporter = new CustomReporter(); | |
jasmineEnv.addReporter(customReporter); | |
jasmineEnv.execute(); | |
console.log('executed test') | |
await new Promise((resolve) => { | |
const checkTestsFinished = setInterval(() => { | |
if (customReporter.finished) { | |
clearInterval(checkTestsFinished); | |
resolve(); | |
} | |
}, 100); | |
}); | |
return customReporter.result; | |
})(); | |
` | |
)(unsafeWindow, jasmine, describe,it,jQuery, jQuery, chai.expect); | |
return executeTest; | |
} catch (e) { | |
return { | |
success: false, | |
error: e.message, | |
stack: e.stack | |
} | |
} | |
} | |
// Setup GM.communicator | |
const com = GM.communicator(); | |
// Add the handler | |
com.registerHandler(location.hash.substring(1), async (payload, sendResponse) => { | |
const code = payload.code; | |
const test = payload.test; | |
console.log('got code', code, test) | |
const result = await runCode(code, test) | |
console.log('run result', result) | |
result.success = result.success || result.overallStatus === 'passed' | |
sendResponse(result) | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment