Skip to content
Commits on Source (80)
......@@ -68,9 +68,19 @@ jobs:
- restore_cache:
key: node-v1-{{ checksum "package.json" }}-{{ arch }}
# remove detox from CI until is fixed
# - run:
# name: Install detox
# command:
# |
# HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew
# HOMEBREW_NO_AUTO_UPDATE=1 brew install --HEAD applesimutils
# npm install -g detox-cli
# npm install -g detox
# not using a workspace here as Node and Yarn versions
# differ between our macOS executor image and the Docker containers above
- run: yarn install
- run: yarn install --frozen-lockfile
- save_cache:
key: yarn-v1-{{ checksum "yarn.lock" }}-{{ arch }}
......@@ -107,6 +117,11 @@ jobs:
paths:
- ios/Pods
# remove detox from CI until is fixed
# Run e2e
# - run: detox build -c ios.sim.release
# - run: detox test -c ios.sim.release --cleanup
### TODO- get tests running with fastlane
......
......@@ -36,29 +36,6 @@ build:android:
expire_in: 7 days
when: on_success
e2e:browserstacks:
image: node:10.16.3
stage: e2e
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
script:
- yarn install
- export bsAPP=`curl -u "${bsUSER}:${bsKEY}" -X POST "https://api-cloud.browserstack.com/app-automate/upload" -F "file=@./Minds-$CI_BUILD_REF_SLUG.apk"| grep -o 'bs\:\/\/.*"' | sed 's/.$//'`
- yarn e2e
tags:
- docker
dependencies:
- build:android
only:
refs:
- /^stable-*/
- /^release-*/
- /^feat-*/
- /^test-*/
allow_failure: true
deploy:s3:
image: minds/ci:latest
stage: deploy
......
......@@ -15,6 +15,7 @@ import {
} from 'mobx-react/native'; // import from mobx-react/native instead of mobx-react fix test
import NavigationService from './src/navigation/NavigationService';
import RNBootSplash from "react-native-bootsplash";
import {
BackHandler,
......@@ -24,6 +25,7 @@ import {
Text,
Alert,
Clipboard,
StatusBar,
} from 'react-native';
import FlashMessage from 'react-native-flash-message';
......@@ -63,6 +65,8 @@ import boostedContentService from './src/common/services/boosted-content.service
let deepLinkUrl = '';
const statusBarStyle = Platform.OS === 'ios' ? 'dark-content' : 'default';
// init push service
pushService.init();
......@@ -94,6 +98,10 @@ sessionService.onLogin(async () => {
pushService.registerToken();
logService.info('[App] navigating to initial screen', sessionService.initialScreen);
// hide splash
RNBootSplash.hide({ duration: 250 });
NavigationService.navigate(sessionService.initialScreen);
// check onboarding progress and navigate if necessary
......@@ -135,13 +143,10 @@ sessionService.onLogin(async () => {
//on app logout
sessionService.onLogout(() => {
// clear app badge
badgeService.setUnreadConversations(0);
badgeService.setUnreadNotifications(0);
// clear minds settings
mindsService.clear();
// clear offline cache
entitiesStorage.removeAll();
feedsStorage.removeAll();
......@@ -181,10 +186,14 @@ export default class App extends Component<Props, State> {
}
/**
* On component will mount
* contructor
*/
componentWillMount() {
if (!Text.defaultProps) Text.defaultProps = {};
constructor(props) {
super(props);
if (!Text.defaultProps) {
Text.defaultProps = {};
}
Text.defaultProps.style = {
fontFamily: 'Roboto',
color: '#444',
......@@ -213,6 +222,7 @@ export default class App extends Component<Props, State> {
if (!token) {
logService.info('[App] there is no active session');
RNBootSplash.hide({ duration: 250 });
NavigationService.navigate('Login');
} else {
logService.info('[App] session initialized');
......@@ -289,6 +299,7 @@ export default class App extends Component<Props, State> {
const app = (
<Provider key="app" {...stores}>
<ErrorBoundary message="An error occurred" containerStyle={CS.centered}>
<StatusBar barStyle={statusBarStyle} />
<NavigationStack
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
......
......@@ -39,7 +39,9 @@ if (process.env.JEST_WORKER_ID === undefined) {
return null;
}
// only log api 500 errors
if (isApiError(hint.originalException) && hint.originalException.status < 500) {
if (isApiError(hint.originalException) &&
(isNaN(hint.originalException.status) || hint.originalException.status < 500)
) {
return null;
}
}
......
......@@ -28,14 +28,31 @@
- iOS
- Android
## Building
## Install dependencies
- `yarn install`
- `cd ios && pod install` (iOS only)
## Building
- `yarn android` or `yarn ios`
## Testing
- `yarn test`
## Testing e2e (macOS)
Install the detox cli
- `brew tap wix/brew`
- `brew install applesimutils`
- `yarn global add detox-cli`
Run the tests
- `detox build -c ios.sim.debug`
- `detox test -c ios.sim.debug`
You can use -c ios.sim.release for e2e test a production build
### _Copyright Minds 2018_
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver) => {
// should ask for permissions
const permmision = await driver.waitForElementById('com.android.packageinstaller:id/permission_allow_button', wd.asserters.isDisplayed, 10000)
// we accept
permmision.click();
}
\ No newline at end of file
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver) => {
// select first image
const firstImage = await driver.waitForElementByAccessibilityId('Gallery image/jpeg', wd.asserters.isDisplayed, 5000);
await firstImage.click();
await sleep(3000);
}
\ No newline at end of file
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver, amount) => {
const lockButton = await driver.waitForElementByAccessibilityId('Post lock button', wd.asserters.isDisplayed, 5000);
await lockButton.click();
const postInput = await driver.waitForElementByAccessibilityId('Poster lock amount input', wd.asserters.isDisplayed, 5000);
await postInput.type(amount);
// we press post button
const postButton = await driver.elementByAccessibilityId('Poster lock done button');
await postButton.click();
}
\ No newline at end of file
export default async(driver) => {
const username = await driver.elementByAccessibilityId('username input');
const password = await driver.elementByAccessibilityId('password input');
const loginButton = await driver.elementByAccessibilityId('login button');
await username.type(process.env.loginUser);
await password.type(process.env.loginPass);
await loginButton.click();
}
\ No newline at end of file
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver, text) => {
// post screen must be shown
const postInput = await driver.waitForElementByAccessibilityId('PostInput', wd.asserters.isDisplayed, 5000);
await postInput.type(text);
// we press post button
const postButton = await driver.elementByAccessibilityId('Capture Post Button');
await postButton.click();
}
\ No newline at end of file
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver) => {
// tap the capture button
const button = await driver.waitForElementByAccessibilityId('CaptureButton', wd.asserters.isDisplayed, 10000);
button.click();
return button;
}
\ No newline at end of file
import wd from 'wd';
import sleep from '../../src/common/helpers/sleep';
export default async(driver, options) => {
// tap the toggle button
const button = await driver.waitForElementByAccessibilityId('NSFW button', wd.asserters.isDisplayed, 5000);
await button.click();
// wait until the menu is shown
await sleep(500);
for (let index = 0; index < options.length; index++) {
const name = options[index];
const element = await driver.elementByAccessibilityId(`NSFW ${name}`);
await element.click();
}
let action = new wd.TouchAction(driver);
action.tap({x:100, y:170});
await action.release().perform();
}
\ No newline at end of file
import wd from 'wd';
import reporterFactory from '../tests-helpers/browserstack-reporter.factory';
import post from './actions/post';
import login from './actions/login';
import { driver, capabilities} from './config';
import sleep from '../src/common/helpers/sleep';
import pressCapture from './actions/pressCapture';
import acceptPermissions from './actions/acceptPermissions';
import attachPostGalleryImage from './actions/attachPostGalleryImage';
import selectNsfw from './actions/selectNsfw';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
const data = {sessiondID: null};
jasmine.getEnv().addReporter(reporterFactory(data));
//TODO: add support for ios to this test (xpath)
describe('Activity flow tests', () => {
beforeAll(async () => {
await driver.init(capabilities);
data.sessiondID = await driver.getSessionId();
console.log('BROWSERSTACK_SESSION: ' + data.sessiondID);
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
// we should login
await login(driver);
});
afterAll(async () => {
await driver.quit();
});
it('should post a text and see it in the newsfeed', async () => {
const str = 'My e2e activity';
// press capture button
await pressCapture(driver);
// accept gallery permissions
await acceptPermissions(driver);
// make the post
await post(driver, str);
// should post and return to the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 10000);
// the first element of the list should be the post
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[2]');
expect(await textElement.text()).toBe(str);
});
it('should like the post', async() => {
const likeButton = await driver.waitForElementByAccessibilityId('Thumb up activity button', 5000);
await likeButton.click();
const likeCount = await driver.waitForElementByAccessibilityId('Thumb up count', 5000);
expect(await likeCount.text()).toBe('1');
});
it('should unlike the post', async() => {
const likeButton = await driver.waitForElementByAccessibilityId('Thumb down activity button', 5000);
await likeButton.click();
const likeCount = await driver.waitForElementByAccessibilityId('Thumb down count', 5000);
expect(await likeCount.text()).toBe('1');
});
});
\ No newline at end of file
import factory from '../tests-helpers/e2e-driver.factory';
const customCapabilities = {
'device' : 'Samsung Galaxy S9',
'os_version' : '8.0'
};
let driver, capabilities;
if (process.env.e2elocal) {
[driver, capabilities] = factory('androidLocal', {});
} else {
[driver, capabilities] = factory('browserStack', customCapabilities);
}
export {driver, capabilities} ;
import wd from 'wd';
import reporterFactory from '../tests-helpers/browserstack-reporter.factory';
import { driver, capabilities} from './config';
import post from './actions/post';
import login from './actions/login';
import sleep from '../src/common/helpers/sleep';
import pressCapture from './actions/pressCapture';
import acceptPermissions from './actions/acceptPermissions';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
const data = {sessiondID: null};
jasmine.getEnv().addReporter(reporterFactory(data));
describe('Discovery post edit flow', () => {
beforeAll(async () => {
await driver.init(capabilities);
data.sessiondID = await driver.getSessionId();
console.log('BROWSERSTACK_SESSION: ' + data.sessiondID);
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
// we should login
await login(driver);
});
afterAll(async () => {
await driver.quit();
});
it('should post a text and go to discovery', async () => {
const str = 'My e2e post #mye2epost';
await pressCapture(driver);
await acceptPermissions(driver);
// make the post
await post(driver, str);
// move to discovery
const discoveryTab = await driver.waitForElementByAccessibilityId('Discovery tab button', wd.asserters.isDisplayed, 10000);
await discoveryTab.click();
});
it('should search for the post', async () => {
// select all list
const all = await driver.waitForElementByAccessibilityId('Discovery All', wd.asserters.isDisplayed, 5000);
await all.click();
await sleep(500);
// select latest filter
const latest = await driver.waitForElementByAccessibilityId('Filter latest button', wd.asserters.isDisplayed, 1000);
await latest.click();
await sleep(500);
// search the post
const search = await driver.waitForElementByAccessibilityId('Discovery Search Input', wd.asserters.isDisplayed, 10000);
await search.type('mye2epost');
await sleep(4000);
// activity menu button
const activityMenu = await driver.waitForElementByAccessibilityId('Activity Menu button', wd.asserters.isDisplayed, 5000);
await activityMenu.click();
await sleep(500);
// tap edit
const edit = await driver.waitForElementByAndroidUIAutomator('new UiSelector().text("Edit")', wd.asserters.isDisplayed, 5000);
await edit.click();
// change the text
const editorInput = await driver.waitForElementByAccessibilityId('Post editor input', wd.asserters.isDisplayed, 5000);
await editorInput.type(' edited!');
// tap save
const save = await driver.waitForElementByAccessibilityId('Post editor save button', wd.asserters.isDisplayed, 5000);
await save.click();
// confirm activity text changed
await driver.waitForElementByAndroidUIAutomator('new UiSelector().text("My e2e post #mye2epost edited!")', wd.asserters.isDisplayed, 5000);
});
});
\ No newline at end of file
import wd from 'wd';
import reporterFactory from '../tests-helpers/browserstack-reporter.factory';
import { driver, capabilities} from './config';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
const data = {sessiondID: null};
jasmine.getEnv().addReporter(reporterFactory(data));
describe('Login flow', () => {
let username, password, loginButton;
beforeAll(async () => {
await driver.init(capabilities);
data.sessiondID = await driver.getSessionId();
console.log('BROWSERSTACK_SESSION: ' + data.sessiondID);
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
});
afterAll(async () => {
await driver.quit();
});
it('should shows login error on wrong credentials', async () => {
expect(await driver.hasElementByAccessibilityId('username input')).toBe(true);
expect(await driver.hasElementByAccessibilityId('password input')).toBe(true);
username = await driver.elementByAccessibilityId('username input');
await username.type('myuser');
password = await driver.elementByAccessibilityId('password input');
await password.type('mypass');
loginButton = await driver.elementByAccessibilityId('login button');
await loginButton.click();
// message should appear
await driver.waitForElementByAccessibilityId('loginMsg', wd.asserters.isDisplayed, 5000);
const textElement = await driver.elementByAccessibilityId('loginMsg');
expect(await textElement.text()).toBe('The user credentials were incorrect.');
});
it('should go to newsfeed on successful login', async () => {
// try successfull login
await username.type(process.env.loginUser);
await password.type(process.env.loginPass);
await loginButton.click();
// should open the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 5000);
});
it('should go to login after logout', async () => {
const menu = await driver.elementByAccessibilityId('Main menu button');
// tap menu button
await menu.click();
const logout = await driver.waitForElementByAccessibilityId('Logout', wd.asserters.isDisplayed, 5000);
// tap logout
logout.click();
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
})
});
\ No newline at end of file
import wd from 'wd';
import reporterFactory from '../tests-helpers/browserstack-reporter.factory';
import post from './actions/post';
import login from './actions/login';
import { driver, capabilities} from './config';
import sleep from '../src/common/helpers/sleep';
import pressCapture from './actions/pressCapture';
import acceptPermissions from './actions/acceptPermissions';
import attachPostGalleryImage from './actions/attachPostGalleryImage';
import selectNsfw from './actions/selectNsfw';
import lockPost from './actions/lockPost';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
const data = {sessiondID: null};
jasmine.getEnv().addReporter(reporterFactory(data));
//TODO: add support for ios to this test (xpath)
describe('Post flow tests', () => {
beforeAll(async () => {
await driver.init(capabilities);
data.sessiondID = await driver.getSessionId();
console.log('BROWSERSTACK_SESSION: ' + data.sessiondID);
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
// we should login
await login(driver);
});
afterAll(async () => {
await driver.quit();
});
it('should post a text and see it in the newsfeed', async () => {
const str = 'My e2e post #mye2epost';
// press capture button
await pressCapture(driver);
// accept gallery permissions
await acceptPermissions(driver);
// make the post
await post(driver, str);
// should post and return to the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 10000);
// the first element of the list should be the post
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[2]');
expect(await textElement.text()).toBe(str);
});
it('should remind the previuos post and see it in the newsfeed', async () => {
const str = 'Reminding my own post';
const remindButton = await driver.waitForElementByAccessibilityId('Remind activity button', 5000);
// tap remind
await remindButton.click();
// make the post
await post(driver, str);
// should post and return to the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 10000);
// the first element of the list should be the post
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[2]');
expect(await textElement.text()).toBe(str);
});
it('should post a nsfw and see it in the newsfeed', async () => {
const str = 'My e2e post #mye2epost';
// press capture button
await pressCapture(driver);
// select nsfw
await selectNsfw(driver, ['Nudity', 'Pornography']);
// make the post
await post(driver, str);
// should post and return to the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 10000);
// the first element of the list should be the post
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[2]');
expect(await textElement.text()).toBe(str);
});
it('should post paywalled content', async () => {
// press capture button
await pressCapture(driver);
// deselect nsfw
await selectNsfw(driver, ['Nudity', 'Pornography']);
const str = 'pay me something';
await lockPost(driver, '1');
// make the post with image and no permissions wait
await post(driver, str);
await sleep(1000);
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[3]');
expect(await textElement.text()).toBe('Locked');
});
it('should post an image and see it in the newsfeed', async () => {
const str = 'My e2e post image #mye2epostimage';
// press capture button
await pressCapture(driver);
// attach image
await attachPostGalleryImage(driver);
// make the post with image and no permissions wait
await post(driver, str);
// should post and return to the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 10000);
// the first element of the list should be the post
const textElement = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Newsfeed Screen"]/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[2]/android.view.ViewGroup/android.widget.TextView[2]');
expect(await textElement.text()).toBe(str);
});
it('should open the images in full screen after tap', async () => {
// get the Image touchable
const imageButton = await driver.waitForElementByAccessibilityId('Posted Image', wd.asserters.isDisplayed, 10000);
await imageButton.click();
const image = await driver.waitForElementByXPath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.widget.ImageView');
const goBack = await driver.waitForElementByAccessibilityId('Go back button', wd.asserters.isDisplayed, 10000);
await goBack.click();
});
it('should upload an image and cancel it', async () => {
// press capture button
await pressCapture(driver);
// attach image
await attachPostGalleryImage(driver);
await sleep(5000);
// we press post button
const deleteButton = await driver.elementByAccessibilityId('Attachment Delete Button');
await deleteButton.click();
await sleep(1000);
// should fail to find the delete button
return expect(driver.elementByAccessibilityId('Attachment Delete Button')).rejects.toHaveProperty('status', 7);
});
it('should return to the newsfeed', async () => {
// tap the back button
await driver.back();
// should open the newsfeed
await driver.waitForElementByAccessibilityId('Newsfeed Screen', wd.asserters.isDisplayed, 5000);
});
});
\ No newline at end of file
import wd from 'wd';
import reporterFactory from '../tests-helpers/browserstack-reporter.factory';
import login from './actions/login';
import { driver, capabilities} from './config';
import sleep from '../src/common/helpers/sleep';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
const data = {sessiondID: null};
jasmine.getEnv().addReporter(reporterFactory(data));
//TODO: add support for ios to this test (xpath)
describe('Top-bar tests', () => {
beforeAll(async () => {
await driver.init(capabilities);
data.sessiondID = await driver.getSessionId();
console.log('BROWSERSTACK_SESSION: ' + data.sessiondID);
await driver.waitForElementByAccessibilityId('username input', wd.asserters.isDisplayed, 5000);
// we should login
await login(driver);
});
afterAll(async () => {
await driver.quit();
});
it('should open the boost console', async () => {
const button = await driver.waitForElementByAccessibilityId('boost-console button', wd.asserters.isDisplayed, 7000);
await button.click();
const textElement = await driver.waitForElementByXPath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[2]/android.widget.TextView');
expect(await textElement.text()).toBe('Boost Console');
const back = await driver.waitForElementByXPath('//android.widget.Button[@content-desc="Go back"]/android.view.ViewGroup/android.widget.ImageView');
back.click();
});
it('should open the users profile on clicking the profile avatar', async () => {
const button = await driver.waitForElementByAccessibilityId('topbar avatar button', wd.asserters.isDisplayed, 5000);
await button.click();
await driver.waitForElementByXPath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[3]/android.widget.ImageView');
const back = await driver.waitForElementByXPath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[2]/android.widget.TextView'); back.click();
});
it('should open the menu when clicking the hamburger menu', async () => {
const button = await driver.waitForElementByAccessibilityId('Main menu button', wd.asserters.isDisplayed, 5000);
await button.click();
const logoutButton = await driver.waitForElementByXPath('//android.view.ViewGroup[@content-desc="Logout"]/android.widget.TextView[2]');
expect(await logoutButton.text()).toBe('Logout');
const back = await driver.waitForElementByXPath('//android.widget.Button[@content-desc="Go back"]/android.view.ViewGroup/android.widget.ImageView');
back.click();
});
});
......@@ -9,6 +9,7 @@ import {
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));
// mock backhandler
......
......@@ -29,6 +29,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -36,6 +37,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -87,6 +89,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -94,6 +97,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -161,6 +165,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -168,6 +173,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -263,6 +269,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -270,6 +277,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -332,6 +340,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -339,6 +348,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -397,6 +407,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -404,6 +415,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -468,6 +480,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -475,6 +488,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......@@ -532,6 +546,7 @@ exports[`Activity component renders correctly 1`] = `
"description": "Congratulations! ",
"edited": "",
"guid": "activityguid0",
"isOwner": [Function],
"is_visible": true,
"mature": false,
"mature_visibility": false,
......@@ -539,6 +554,7 @@ exports[`Activity component renders correctly 1`] = `
"ownerObj": UserModel {
"__list": null,
"guid": "824853017709780997",
"isOwner": [Function],
"subtype": false,
"time_created": "1522036284",
"type": "user",
......