feat: mobile app package (#1075)

This commit is contained in:
Mo
2022-06-09 09:45:15 -05:00
committed by GitHub
parent 58b63898de
commit 8248a38280
336 changed files with 47696 additions and 22563 deletions

View File

@@ -0,0 +1,58 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const faker = require('faker')
import { by, device, element, expect, waitFor } from 'detox'
export const expectToBeVisible = async (testedElement: Detox.IndexableNativeElement) => {
try {
await expect(testedElement).toBeVisible()
return true
} catch (e) {
return false
}
}
const checkAfterReinstall = async () => {
if (device.getPlatform() === 'ios') {
const alertElement = element(
by.label('Delete Local Data').and(by.type('_UIAlertControllerActionView'))
)
const alertVisible = await expectToBeVisible(alertElement)
if (alertVisible) {
await element(
by.label('Delete Local Data').and(by.type('_UIAlertControllerActionView'))
).tap()
}
}
}
export const openSettingsScreen = async () => {
await checkAfterReinstall()
await device.reloadReactNative()
// Opens the settings screen
await waitFor(element(by.id('rootView')))
.toBeVisible()
.withTimeout(2000)
await element(by.id('headerButton')).tap()
await element(by.id('settingsButton')).tap()
}
export const openComposeNewNoteScreen = async () => {
await device.reloadReactNative()
// Opens the screen to compose a new note
await waitFor(element(by.id('rootView')))
.toBeVisible()
.withTimeout(2000)
await waitFor(element(by.id('newNoteButton')))
.toBeVisible()
.withTimeout(2000)
await element(by.id('newNoteButton')).tap()
}
export const randomCredentials = {
email: faker.internet.exampleEmail(),
password: faker.internet.password(),
syncServerUrl: 'https://app-dev.standardnotes.com',
}

View File

@@ -0,0 +1,103 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const helpers = require('../../Helpers')
import { by, device, element, expect, waitFor } from 'detox'
import { openSettingsScreen } from '../../Helpers'
console.log('aaaa is', helpers)
// console.log('bbbb is', helpers2)
console.log('cccc is', helpers.openSettingsScreen === openSettingsScreen)
fdescribe('Account section', () => {
describe('Form', () => {
beforeAll(async () => {
await helpers.openSettingsScreen()
})
it('should have the "Email" and "Password" fields visible', async () => {
await expect(element(by.id('emailField'))).toBeVisible()
await expect(element(by.id('passwordField'))).toBeVisible()
})
it('should have the "Sign In" button visible', async () => {
await expect(element(by.id('signInButton'))).toBeVisible()
})
it('should have the "Register" button visible', async () => {
await expect(element(by.id('registerButton'))).toBeVisible()
})
it('should have the "Other Options" button visible', async () => {
await expect(element(by.id('otherOptionsButton'))).toBeVisible()
})
it('should have the "Sync Server" field visible when "Other Options" button is pressed', async () => {
await element(by.id('otherOptionsButton')).tap()
await expect(element(by.id('syncServerField'))).toBeVisible()
})
})
describe('Register', () => {
beforeAll(async () => {
await helpers.openSettingsScreen()
})
it('should work when valid data is provided', async () => {
await element(by.id('emailField')).typeText(helpers.randomCredentials.email)
await element(by.id('passwordField')).typeText(helpers.randomCredentials.password)
await element(by.id('otherOptionsButton')).tap()
await element(by.id('syncServerField')).clearText()
await element(by.id('syncServerField')).typeText(
helpers.randomCredentials.syncServerUrl + '\n'
)
// wait for buttons to be visible after closing keyboard on smaller devices
await waitFor(element(by.id('registerButton')))
.toBeVisible()
.withTimeout(1000)
await element(by.id('registerButton')).tap()
// A confirmation screen is shown after we click the register button...
await expect(element(by.id('passwordConfirmationField'))).toBeVisible()
await expect(element(by.id('registerConfirmButton'))).toBeVisible()
// Password confirmation is required...
await element(by.id('passwordConfirmationField')).typeText(helpers.randomCredentials.password)
await element(by.id('registerConfirmButton')).tap()
})
afterAll(async () => {
await helpers.openSettingsScreen()
// Account is created and we now proceed to sign out...
await expect(element(by.id('signOutButton'))).toBeVisible()
await element(by.id('signOutButton')).tap()
// Confirmation button in the dialog...
if (device.getPlatform() === 'ios') {
await element(by.label('Sign Out').and(by.type('_UIAlertControllerActionView'))).tap()
} else {
await expect(element(by.text('SIGN OUT'))).toBeVisible()
await element(by.text('SIGN OUT')).tap()
}
})
})
describe('Sign In', () => {
beforeAll(async () => {
await helpers.openSettingsScreen()
})
it('should work when valid data is provided', async () => {
await element(by.id('emailField')).typeText(helpers.randomCredentials.email)
await element(by.id('passwordField')).typeText(helpers.randomCredentials.password)
await element(by.id('otherOptionsButton')).tap()
await element(by.id('syncServerField')).clearText()
await element(by.id('syncServerField')).typeText(
helpers.randomCredentials.syncServerUrl + '\n'
)
// wait for button to be visible after keyboard close
await waitFor(element(by.id('signInButton')))
.toBeVisible()
.withTimeout(1000)
await element(by.id('signInButton')).tap()
})
})
})

View File

@@ -0,0 +1,36 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const helpers = require('../../Helpers')
import { by, device, element, expect } from 'detox'
describe('Options section', () => {
beforeAll(async () => {
await helpers.openSettingsScreen()
})
describe('Export Data', () => {
it('should have the option visible', async () => {
await expect(element(by.id('exportData'))).toBeVisible()
await expect(element(by.id('exportData-title'))).toHaveText('Export Data')
})
it('should restore to "Export Data" if dialog is dismissed', async () => {
await expect(element(by.id('exportData-option-decrypted'))).toBeVisible()
if (device.getPlatform() === 'android') {
await element(by.id('exportData-option-decrypted')).tap()
await device.pressBack()
await expect(element(by.id('exportData-title'))).toHaveText('Export Data')
}
})
it('should export decrypted notes', async () => {
await expect(element(by.id('exportData-option-decrypted'))).toBeVisible()
if (device.getPlatform() === 'android') {
await element(by.id('exportData-option-decrypted')).tap()
await element(by.text('SAVE TO DISK')).tap()
await element(by.text('DONE')).tap()
await expect(element(by.id('exportData-title'))).toHaveText('Export Data')
}
})
})
})

View File

@@ -0,0 +1,7 @@
{
"setupFilesAfterEnv": ["./init.js"],
"testEnvironment": "detox/runners/jest/JestCircusEnvironment",
"testRunner": "jest-circus/runner",
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true
}

View File

@@ -0,0 +1,37 @@
/* eslint-disable no-undef */
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');
const assignReporter = require('detox/runners/jest/assignReporter');
// Set the default timeout
jest.setTimeout(120000);
detoxCircus.getEnv().addEventsListener(adapter);
detoxCircus.getEnv().addEventsListener(specReporter);
detoxCircus.getEnv().addEventsListener(assignReporter);
beforeAll(async () => {
await detox.init(config);
}, 600000);
// beforeEach(async () => {
// try {
// await adapter.beforeEach();
// } catch (err) {
// // Workaround for the 'jest-jasmine' runner (default one): if 'beforeAll' hook above fails with a timeout,
// // unfortunately, 'jest' might continue running other hooks and test suites. To prevent that behavior,
// // adapter.beforeEach() will throw if detox.init() is still running; that allows us to run detox.cleanup()
// // in that emergency case and disable calling 'device', 'element', 'expect', 'by' and other Detox globals.
// // If you switch to 'jest-circus' runner, you can omit this try-catch workaround at all.
// await detox.cleanup();
// throw err;
// }
// });
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});