Handle Android back navigation in app
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const test = require('node:test');
|
||||
const vm = require('node:vm');
|
||||
|
||||
const script = fs.readFileSync(
|
||||
new URL('../static/js/android-back-button.js', `file://${__filename}`),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
function createHarness({platform = 'android', pathname = '/', openDialog = false, openDetails = false} = {}) {
|
||||
const calls = [];
|
||||
const dialog = {close: () => calls.push('dialog.close')};
|
||||
const details = {open: true};
|
||||
const capacitor = {
|
||||
getPlatform: () => platform,
|
||||
addListener: (plugin, event, handler) => {
|
||||
calls.push(`listener:${plugin}:${event}`);
|
||||
capacitor.backHandler = handler;
|
||||
return {remove: async () => {}};
|
||||
},
|
||||
nativePromise: (plugin, method) => {
|
||||
calls.push(`${plugin}.${method}`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
vm.runInNewContext(script, {
|
||||
window: {Capacitor: capacitor},
|
||||
document: {
|
||||
querySelector: selector => selector === 'dialog[open]'
|
||||
? (openDialog ? dialog : null)
|
||||
: (openDetails ? details : null)
|
||||
},
|
||||
location: {pathname, replace: path => calls.push(`replace:${path}`)},
|
||||
history: {back: () => calls.push('history.back')}
|
||||
});
|
||||
return {calls, capacitor, details};
|
||||
}
|
||||
|
||||
test('Android back closes an open dialog or details panel first', () => {
|
||||
const dialog = createHarness({openDialog: true});
|
||||
dialog.capacitor.backHandler({canGoBack: true});
|
||||
assert.deepEqual(dialog.calls, ['listener:App:backButton', 'dialog.close']);
|
||||
|
||||
const details = createHarness({openDetails: true});
|
||||
details.capacitor.backHandler({canGoBack: true});
|
||||
assert.equal(details.details.open, false);
|
||||
assert.deepEqual(details.calls, ['listener:App:backButton']);
|
||||
});
|
||||
|
||||
test('Android back follows WebView history away from the start page', () => {
|
||||
const {calls, capacitor} = createHarness({pathname: '/messages'});
|
||||
capacitor.backHandler({canGoBack: true});
|
||||
assert.deepEqual(calls, ['listener:App:backButton', 'history.back']);
|
||||
});
|
||||
|
||||
test('Android back returns to the start page when a deep link has no history', () => {
|
||||
const {calls, capacitor} = createHarness({pathname: '/messages/42'});
|
||||
capacitor.backHandler({canGoBack: false});
|
||||
assert.deepEqual(calls, ['listener:App:backButton', 'replace:/']);
|
||||
});
|
||||
|
||||
test('Android back exits only from the start page', () => {
|
||||
const {calls, capacitor} = createHarness();
|
||||
capacitor.backHandler({canGoBack: false});
|
||||
assert.deepEqual(calls, ['listener:App:backButton', 'App.exitApp']);
|
||||
});
|
||||
|
||||
test('web browsers do not register the native back handler', () => {
|
||||
const {calls} = createHarness({platform: 'web'});
|
||||
assert.deepEqual(calls, []);
|
||||
});
|
||||
Reference in New Issue
Block a user