Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Node CIGitHub versionnpm version

Cordova Plugin Test Framework

The cordova-plugin-test-framework plugin allows plugin authors to add tests (manual and automated) to their plugins. To achieve this it

  1. defines the interface for Cordova plugins to write tests and
  2. provides a test harness for actually running those tests

Tests run directly inside existing Cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using.

TLDR; Try it

  1. Use your existing Cordova app, or create a new one.

  2. Plugins bundle their tests using a nested plugin in a /tests directory. Here are a few examples how install both:

    cordova plugin add cordova-plugin-device
    cordova plugin add plugins/cordova-plugin-device/tests
    cordova plugin add cordova-plugin-device-motion
    cordova plugin add plugins/cordova-plugin-device-motion/tests
    cordova plugin add cordova-plugin-geolocation
    cordova plugin add plugins/cordova-plugin-geolocation/tests

    To install the plugin from master on GitHub instead of npm, replace e.g. cordova-plugin-device with https://github.com/apache/cordova-plugin-device.git

  3. Follow the docs for Setting up the test harness.

Where do tests live?

Add a directory named tests to the root of your plugin. Within this directory, create a nested plugin.xml for the tests plugin. It should have a plugin id with the form pluginid-tests (e.g. the cordova-plugin-device plugin has the nested id cordova-plugin-device-tests) and should contain a <js-module> named tests. E.g:

<js-module src="tests/tests.js" name="tests">
</js-module>

For example, the cordova-plugin-device plugin has this nested plugin.xml.

Create a package.json inside your project's tests/ folder. Plugins require a package.json now and tests are considered their own plugins. The latest version of the tools ensure to run npm install on any plugin added to a project and pull in any dependencies. Therefore, plugin authors can now put npm dependencies around their tests into the package.json file.

For example, the cordova-plugin-device plugin contains a package.json.

The cordova-plugin-test-framework plugin will automatically find all tests modules across all plugins for which the nested tests plugin is installed.

Defining Auto Tests

Export a function named defineAutoTests, which defines your auto-tests when run. Use the jasmine-2.9 format. E.g.:

exports.defineAutoTests = function() {
describe('awesome tests', function() {
it('do something sync', function() {
expect(1).toBe(1);
...
});
it('do something async using callbacks', function(done) {
setTimeout(function() {
expect(1).toBe(1);
...
done();
}, 100);
});
it("do something async using promises", function() {
return soon().then(function() {
value++;
expect(value).toBeGreaterThan(0);
});
});
it("do something async using async/await", async function() {
await soon();
value++;
expect(value).toBeGreaterThan(0);
});
});
describe('more awesome tests', function() {
...
});
};

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

Defining Manual Tests

Export a function named defineManualTests, which defines your manual-tests when run. Manual tests do not any test runner, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using console or by manipulating a provided DOM element. E.g.:

exports.defineManualTests = function(contentEl, createActionButton) {
createActionButton('Simple Test', function() {
console.log(JSON.stringify(foo, null, '\t'));
});
createActionButton('Complex Test', function() {
contentEl.innerHTML = ...;
});
};

Make sure to document the expected outcome.

Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions.

See: cordova-plugin-device tests.

  1. Use your existing Cordova app, or create a new one.

  2. Add this plugin:

    cordova plugin add cordova-plugin-test-framework
    // or
    cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git
    
  3. Change the start page in config.xml with <content src="cdvtests/index.html" /> or add a link to cdvtests/index.html from within your app.

  4. Thats it!

FAQ

  • Q: Should I add cordova-plugin-test-framework as a <dependency> of my plugin?

    • A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't).
  • Q: What do I do if my plugin tests must have very large assets?

    • A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite.
  • Q: Should I ship my app with the test framework plugin installed?

    • A: Not likely. If you want, you can. Then your app could even embed a link to the test page (cdvtests/index.html) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe.

Releases

Packages

Used by

Contributors

Languages