diff --git a/tests/plugin.xml b/tests/plugin.xml
new file mode 100644
index 0000000..2a386f8
--- /dev/null
+++ b/tests/plugin.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ Cordova InAppBrowser Plugin Tests
+ Apache 2.0
+
+
+
+
+
+
diff --git a/tests/resources/inject.css b/tests/resources/inject.css
new file mode 100644
index 0000000..3f6e41c
--- /dev/null
+++ b/tests/resources/inject.css
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+#style-update-file {
+ display: block !important;
+}
diff --git a/tests/resources/inject.html b/tests/resources/inject.html
new file mode 100644
index 0000000..0f1efdd
--- /dev/null
+++ b/tests/resources/inject.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+ Cordova Mobile Spec
+
+
+
+
InAppBrowser - Script / Style Injection Test
+
Style updated from file
+
Style updated from literal
+
+
+
diff --git a/tests/resources/inject.js b/tests/resources/inject.js
new file mode 100644
index 0000000..6f25493
--- /dev/null
+++ b/tests/resources/inject.js
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+var d = document.getElementById("header")
+d.innerHTML = "Script file successfully injected";
diff --git a/tests/resources/local.html b/tests/resources/local.html
new file mode 100644
index 0000000..5e33800
--- /dev/null
+++ b/tests/resources/local.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+ IAB test page
+
+
+
+
+
Local URL
+
+ You have successfully loaded a local URL:
+
+
+
+
User-Agent =
+
+
Likely running inAppBrowser: Device version from Cordova=not found, Back link should not work, toolbar may be present, logcat should show failed 'gap:' calls.
+
+
+
diff --git a/tests/resources/local.pdf b/tests/resources/local.pdf
new file mode 100644
index 0000000..b54f1b7
Binary files /dev/null and b/tests/resources/local.pdf differ
diff --git a/tests/resources/video.html b/tests/resources/video.html
new file mode 100644
index 0000000..64ea3d1
--- /dev/null
+++ b/tests/resources/video.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+ Cordova Mobile Spec
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/tests.js b/tests/tests.js
new file mode 100644
index 0000000..4a08849
--- /dev/null
+++ b/tests/tests.js
@@ -0,0 +1,457 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+exports.defineManualTests = function (contentEl, createActionButton) {
+
+ function doOpen(url, target, params, numExpectedRedirects) {
+ numExpectedRedirects = numExpectedRedirects || 0;
+ console.log("Opening " + url);
+ var iab = window.open(url, target, params);
+ if (!iab) {
+ alert('window.open returned ' + iab);
+ return;
+ }
+ var counts;
+ var lastLoadStartURL;
+ var wasReset = false;
+ function reset() {
+ counts = {
+ 'loaderror': 0,
+ 'loadstart': 0,
+ 'loadstop': 0,
+ 'exit': 0
+ };
+ lastLoadStartURL = '';
+ }
+ reset();
+
+ function logEvent(e) {
+ console.log('IAB event=' + JSON.stringify(e));
+ counts[e.type]++;
+ // Verify that event.url gets updated on redirects.
+ if (e.type == 'loadstart') {
+ if (e.url == lastLoadStartURL) {
+ alert('Unexpected: loadstart fired multiple times for the same URL.');
+ }
+ lastLoadStartURL = e.url;
+ }
+ // Verify the right number of loadstart events were fired.
+ if (e.type == 'loadstop' || e.type == 'loaderror') {
+ if (e.url != lastLoadStartURL) {
+ alert('Unexpected: ' + e.type + ' event.url != loadstart\'s event.url');
+ }
+ if (numExpectedRedirects === 0 && counts['loadstart'] !== 1) {
+ // Do allow a loaderror without a loadstart (e.g. in the case of an invalid URL).
+ if (!(e.type == 'loaderror' && counts['loadstart'] === 0)) {
+ alert('Unexpected: got multiple loadstart events. (' + counts['loadstart'] + ')');
+ }
+ } else if (numExpectedRedirects > 0 && counts['loadstart'] < (numExpectedRedirects + 1)) {
+ alert('Unexpected: should have got at least ' + (numExpectedRedirects + 1) + ' loadstart events, but got ' + counts['loadstart']);
+ }
+ wasReset = true;
+ numExpectedRedirects = 0;
+ reset();
+ }
+ // Verify that loadend / loaderror was called.
+ if (e.type == 'exit') {
+ var numStopEvents = counts['loadstop'] + counts['loaderror'];
+ if (numStopEvents === 0 && !wasReset) {
+ alert('Unexpected: browser closed without a loadstop or loaderror.')
+ } else if (numStopEvents > 1) {
+ alert('Unexpected: got multiple loadstop/loaderror events.');
+ }
+ }
+ }
+ iab.addEventListener('loaderror', logEvent);
+ iab.addEventListener('loadstart', logEvent);
+ iab.addEventListener('loadstop', logEvent);
+ iab.addEventListener('exit', logEvent);
+
+ return iab;
+ }
+
+ function openWithStyle(url, cssUrl, useCallback) {
+ var iab = doOpen(url, '_blank', 'location=yes');
+ var callback = function (results) {
+ if (results && results.length === 0) {
+ alert('Results verified');
+ } else {
+ console.log(results);
+ alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results));
+ }
+ };
+ if (cssUrl) {
+ iab.addEventListener('loadstop', function (event) {
+ iab.insertCSS({ file: cssUrl }, useCallback && callback);
+ });
+ } else {
+ iab.addEventListener('loadstop', function (event) {
+ iab.insertCSS({ code: '#style-update-literal { \ndisplay: block !important; \n}' },
+ useCallback && callback);
+ });
+ }
+ }
+
+ function openWithScript(url, jsUrl, useCallback) {
+ var iab = doOpen(url, '_blank', 'location=yes');
+ if (jsUrl) {
+ iab.addEventListener('loadstop', function (event) {
+ iab.executeScript({ file: jsUrl }, useCallback && function (results) {
+ if (results && results.length === 0) {
+ alert('Results verified');
+ } else {
+ console.log(results);
+ alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results));
+ }
+ });
+ });
+ } else {
+ iab.addEventListener('loadstop', function (event) {
+ var code = '(function(){\n' +
+ ' var header = document.getElementById("header");\n' +
+ ' header.innerHTML = "Script literal successfully injected";\n' +
+ ' return "abc";\n' +
+ '})()';
+ iab.executeScript({ code: code }, useCallback && function (results) {
+ if (results && results.length === 1 && results[0] === 'abc') {
+ alert('Results verified');
+ } else {
+ console.log(results);
+ alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results));
+ }
+ });
+ });
+ }
+ }
+ var hiddenwnd = null;
+ var loadlistener = function (event) { alert('background window loaded '); };
+ function openHidden(url, startHidden) {
+ var shopt = (startHidden) ? 'hidden=yes' : '';
+ hiddenwnd = window.open(url, 'random_string', shopt);
+ if (!hiddenwnd) {
+ alert('window.open returned ' + hiddenwnd);
+ return;
+ }
+ if (startHidden) hiddenwnd.addEventListener('loadstop', loadlistener);
+ }
+ function showHidden() {
+ if (!!hiddenwnd) {
+ hiddenwnd.show();
+ }
+ }
+ function closeHidden() {
+ if (!!hiddenwnd) {
+ hiddenwnd.removeEventListener('loadstop', loadlistener);
+ hiddenwnd.close();
+ hiddenwnd = null;
+ }
+ }
+
+ var info_div = '
InAppBrowser
' +
+ '
' +
+ 'Make sure http://wwww.google.com is white listed. ' +
+ 'Make sure http://www.apple.com is not in the white list.' +
+ 'In iOS, starred * tests will put the app in a state with no way to return. ' +
+ '
User-Agent: ' +
+ '
';
+
+ var local_tests = '
Local URL
' +
+ '' +
+ 'Expected result: opens successfully in CordovaWebView.' +
+ ' ' +
+ 'Expected result: opens successfully in CordovaWebView.' +
+ ' ' +
+ 'Expected result: fails to open' +
+ ' ' +
+ 'Expected result: opens successfully in InAppBrowser with locationBar at top.' +
+ ' ' +
+ 'Expected result: opens successfully in InAppBrowser without locationBar.' +
+ ' ' +
+ 'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the bottom.' +
+ ' ' +
+ 'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the top.' +
+ '' +
+ 'Expected result: open successfully in InAppBrowser with no locationBar. On iOS the toolbar is at the top.';
+
+ var white_listed_tests = '
White Listed URL
' +
+ '' +
+ 'Expected result: open successfully in CordovaWebView to www.google.com' +
+ ' ' +
+ 'Expected result: open successfully in CordovaWebView to www.google.com' +
+ ' ' +
+ 'Expected result: open successfully in system browser to www.google.com' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to www.google.com' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to www.google.com' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to www.google.com with no location bar.';
+
+ var non_white_listed_tests = '
Non White Listed URL
' +
+ '' +
+ 'Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).' +
+ ' ' +
+ 'Expected result: open successfully in system browser to apple.com.' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to apple.com.' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to apple.com.' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to apple.com without locationBar.';
+
+ var page_with_redirects_tests = '
Page with redirect
' +
+ '' +
+ 'Expected result: should 301 and open successfully in InAppBrowser to www.google.com.' +
+ ' ' +
+ 'Expected result: should 302 and open successfully in InAppBrowser to www.zhihu.com/answer/16714076.';
+
+ var pdf_url_tests = '
PDF URL
' +
+ '' +
+ 'Expected result: InAppBrowser opens. PDF should render on iOS.' +
+ ' ' +
+ 'Expected result: InAppBrowser opens. PDF should render on iOS.';
+
+ var invalid_url_tests = '
Invalid URL
' +
+ '' +
+ 'Expected result: fail to load in InAppBrowser.' +
+ ' ' +
+ 'Expected result: fail to load in InAppBrowser.' +
+ ' ' +
+ 'Expected result: fail to load in InAppBrowser (404).';
+
+ var css_js_injection_tests = '
CSS / JS Injection
' +
+ '' +
+ 'Expected result: open successfully in InAppBrowser without text "Style updated from..."' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with "Style updated from file".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with "Style updated from file", and alert dialog with text "Results verified".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with "Style updated from literal".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with "Style updated from literal", and alert dialog with text "Results verified".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with text "Script file successfully injected".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with text "Script file successfully injected" and alert dialog with the text "Results verified".' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" .' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" and alert dialog with the text "Results verified".';
+
+ var open_hidden_tests = '
Open Hidden
' +
+ '' +
+ 'Expected result: no additional browser window. Alert appears with the text "background window loaded".' +
+ ' ' +
+ 'Expected result: after first clicking on previous test "create hidden", open successfully in InAppBrowser to google.com.' +
+ ' ' +
+ 'Expected result: no output. But click on "show hidden" again and nothing should be shown.' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to www.google.com';
+
+ var clearing_cache_tests = '
' +
+ '' +
+ 'Expected result: open successfully in InAppBrowser with an embedded video that works after clicking the "play" button.';
+
+ var local_with_anchor_tag_tests = '
Local with anchor tag
' +
+ '' +
+ 'Expected result: open successfully in InAppBrowser to the local page, scrolled to the top.' +
+ ' ' +
+ 'Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.';
+
+ contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests +
+ css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests;
+
+ var basePath = '/www/resources/';
+ var localhtml = basePath + 'local.html',
+ localpdf = basePath + 'local.pdf',
+ injecthtml = basePath + 'inject.html',
+ injectjs = basePath + 'inject.js',
+ injectcss = basePath + 'inject.css',
+ videohtml = basePath + 'video.html';
+
+ //Local
+ createActionButton('target=Default', function () {
+ console.log(localhtml);
+ //doOpen(localhtml);
+ }, 'openLocal');
+ createActionButton('target=_self', function () {
+ doOpen(localhtml, '_self');
+ }, 'openLocalSelf');
+ createActionButton('target=_system', function () {
+ doOpen(localhtml, '_system');
+ }, 'openLocalSystem');
+ createActionButton('target=_blank', function () {
+ doOpen(localhtml, '_blank');
+ }, 'openLocalBlank');
+ createActionButton('target=Random, location=no, disallowoverscroll=yes', function () {
+ doOpen(localhtml, 'random_string', 'location=no, disallowoverscroll=yes');
+ }, 'openLocalRandomNoLocation');
+ createActionButton('target=Random, toolbarposition=bottom', function () {
+ doOpen(localhtml, 'random_string', 'toolbarposition=bottom');
+ }, 'openLocalRandomToolBarBottom');
+ createActionButton('target=Random, toolbarposition=top', function () {
+ doOpen(localhtml, 'random_string', 'toolbarposition=top');
+ }, 'openLocalRandomToolBarTop');
+ createActionButton('target=Random, toolbarposition=top, location=no', function () {
+ doOpen(localhtml, 'random_string', 'toolbarposition=top,location=no');
+ }, 'openLocalRandomToolBarTopNoLocation');
+
+ //White Listed
+ createActionButton('* target=Default', function () {
+ doOpen('http://www.google.com');
+ }, 'openWhiteListed');
+ createActionButton('* target=_self', function () {
+ doOpen('http://www.google.com', '_self');
+ }, 'openWhiteListedSelf');
+ createActionButton('target=_system', function () {
+ doOpen('http://www.google.com', '_system');
+ }, 'openWhiteListedSystem');
+ createActionButton('target=_blank', function () {
+ doOpen('http://www.google.com', '_blank');
+ }, 'openWhiteListedBlank');
+ createActionButton('target=Random', function () {
+ doOpen('http://www.google.com', 'random_string');
+ }, 'openWhiteListedRandom');
+ createActionButton('* target=Random, no location bar', function () {
+ doOpen('http://www.google.com', 'random_string', 'location=no');
+ }, 'openWhiteListedRandomNoLocation');
+
+ //Non White Listed
+ createActionButton('target=Default', function () {
+ doOpen('http://www.apple.com');
+ }, 'openNonWhiteListed');
+ createActionButton('target=_self', function () {
+ doOpen('http://www.apple.com', '_self');
+ }, 'openNonWhiteListedSelf');
+ createActionButton('target=_system', function () {
+ doOpen('http://www.apple.com', '_system');
+ }, 'openNonWhiteListedSystem');
+ createActionButton('target=_blank', function () {
+ doOpen('http://www.apple.com', '_blank');
+ }, 'openNonWhiteListedBlank');
+ createActionButton('target=Random', function () {
+ doOpen('http://www.apple.com', 'random_string');
+ }, 'openNonWhiteListedRandom');
+ createActionButton('* target=Random, no location bar', function () {
+ doOpen('http://www.apple.com', 'random_string', 'location=no');
+ }, 'openNonWhiteListedRandomNoLocation');
+
+ //Page with redirect
+ createActionButton('http://google.com', function () {
+ doOpen('http://google.com', 'random_string', '', 1);
+ }, 'openRedirect301');
+ createActionButton('http://goo.gl/pUFqg', function () {
+ doOpen('http://goo.gl/pUFqg', 'random_string', '', 2);
+ }, 'openRedirect302');
+
+ //PDF URL
+ createActionButton('Remote URL', function () {
+ doOpen('http://www.stluciadance.com/prospectus_file/sample.pdf');
+ }, 'openPDF');
+ createActionButton('Local URL', function () {
+ doOpen(localpdf, '_blank');
+ }, 'openPDFBlank');
+
+ //Invalid URL
+ createActionButton('Invalid Scheme', function () {
+ doOpen('x-ttp://www.invalid.com/', '_blank');
+ }, 'openInvalidScheme');
+ createActionButton('Invalid Host', function () {
+ doOpen('http://www.inv;alid.com/', '_blank');
+ }, 'openInvalidHost');
+ createActionButton('Missing Local File', function () {
+ doOpen('nonexistent.html', '_blank');
+ }, 'openInvalidMissing');
+
+ //CSS / JS injection
+ createActionButton('Original Document', function () {
+ doOpen(injecthtml, '_blank');
+ }, 'openOriginalDocument');
+ createActionButton('CSS File Injection', function () {
+ openWithStyle(injecthtml, injectcss);
+ }, 'openCSSInjection');
+ createActionButton('CSS File Injection (callback)', function () {
+ openWithStyle(injecthtml, injectcss, true);
+ }, 'openCSSInjectionCallback');
+ createActionButton('CSS Literal Injection', function () {
+ openWithStyle(injecthtml);
+ }, 'openCSSLiteralInjection');
+ createActionButton('CSS Literal Injection (callback)', function () {
+ openWithStyle(injecthtml, null, true);
+ }, 'openCSSLiteralInjectionCallback');
+ createActionButton('Script File Injection', function () {
+ openWithScript(injecthtml, injectjs);
+ }, 'openScriptInjection');
+ createActionButton('Script File Injection (callback)', function () {
+ openWithScript(injecthtml, injectjs, true);
+ }, 'openScriptInjectionCallback');
+ createActionButton('Script Literal Injection', function () {
+ openWithScript(injecthtml);
+ }, 'openScriptLiteralInjection');
+ createActionButton('Script Literal Injection (callback)', function () {
+ openWithScript(injecthtml, null, true);
+ }, 'openScriptLiteralInjectionCallback');
+
+ //Open hidden
+ createActionButton('Create Hidden', function () {
+ openHidden('http://google.com', true);
+ }, 'openHidden');
+ createActionButton('Show Hidden', function () {
+ showHidden();
+ }, 'showHidden');
+ createActionButton('Close Hidden', function () {
+ closeHidden();
+ }, 'closeHidden');
+ createActionButton('google.com Not Hidden', function () {
+ openHidden('http://google.com', false);
+ }, 'openHiddenShow');
+
+ //Clearing cache
+ createActionButton('Clear Browser Cache', function () {
+ doOpen('http://www.google.com', '_blank', 'clearcache=yes');
+ }, 'openClearCache');
+ createActionButton('Clear Session Cache', function () {
+ doOpen('http://www.google.com', '_blank', 'clearsessioncache=yes');
+ }, 'openClearSessionCache');
+
+ //Video tag
+ createActionButton('Remote Video', function () {
+ doOpen(videohtml, '_blank');
+ }, 'openRemoteVideo');
+
+ //Local With Anchor Tag
+ createActionButton('Anchor1', function () {
+ doOpen(localhtml + '#anchor1', '_blank');
+ }, 'openAnchor1');
+ createActionButton('Anchor2', function () {
+ doOpen(localhtml + '#anchor2', '_blank');
+ }, 'openAnchor2');
+};
+