Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions .github/workflows/ci-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: App CI Pipeline
on:
push:
paths:
- "app/**"
- 'app/**'
pull_request:
paths:
- "app/**"
- 'app/**'

jobs:
build:
Expand Down Expand Up @@ -41,3 +41,64 @@ jobs:
- name: Run tests
run: yarn run test
working-directory: ./app

ios-e2e-tests:
needs: build
timeout-minutes: 60
runs-on: macos-latest
steps:
- uses: actions/checkout@v3

# Cache Yarn dependencies
- uses: actions/cache@v2
with:
path: |
.yarn/cache
./app/node_modules
key: ${{ runner.os }}-yarn-${{ hashFiles('./app/**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

- name: Install yarn
run: npm install -g yarn

- name: Install dependencies
run: yarn install
working-directory: ./app

# Cache CocoaPods
- uses: actions/cache@v2
with:
path: ./app/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('./app/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-

- name: Install CocoaPods
run: sudo gem install cocoapods

- name: Install Pods
run: cd app/ios && pod install

# Tap wix/brew for applesimutils
- name: Tap wix/brew
run: brew tap wix/brew

- name: Install applesimutils
run: brew install wix/brew/applesimutils

# Cache Detox build artifacts
- uses: actions/cache@v2
with:
path: ./app/ios/build
key: ${{ runner.os }}-detox-build-${{ hashFiles('./app/**/*.js', './app/**/*.jsx', './app/**/yarn.lock', './app/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-detox-build-

- name: Run Detox build
run: yarn e2e:build ios.sim.release
working-directory: ./app

- name: Run Detox tests
run: yarn e2e:test ios.sim.release --cleanup
working-directory: ./app
9 changes: 6 additions & 3 deletions app/e2e/login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import { login } from './utils.js';

describe('Login', () => {
beforeAll(async () => {
await device.launchApp();
await device.launchApp({
permissions: { location: 'always' },
launchArgs: { detoxPrintBusyIdleResources: 'YES' },
});
});

beforeEach(async () => {
await device.reloadReactNative();
});

it('disallow login with bad credentials', async () => {
await element(by.id('username')).typeText('invalid_username');
await element(by.id('password')).typeText('invalid_password');
await element(by.id('username')).typeText('invalid_username\n');
await element(by.id('password')).typeText('invalid_password\n');
await element(by.text('Se connecter')).tap();
await expect(element(by.id('loginError'))).toBeVisible();
});
Expand Down
17 changes: 8 additions & 9 deletions app/e2e/navigate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { login } from './utils.js';

describe('Navigation', () => {
beforeAll(async () => {
await device.launchApp();
await device.launchApp({
permissions: { location: 'always' },
launchArgs: { detoxPrintBusyIdleResources: 'YES' },
});
await login();
await login();
});
Expand All @@ -14,22 +17,18 @@ describe('Navigation', () => {

// Tattoo artists list tab
await element(by.id('tab-tatoueurs')).tap();
await expect(element(by.label('Tatoueurs'))).toBeVisible();

await waitFor(element(by.id('tab-messagerie')))
.toBeVisible()
.withTimeout(5000);
await expect(element(by.label('Tatoueurs')).atIndex(0)).toBeVisible();

// Messaging tab
await element(by.id('tab-messagerie')).tap();
await expect(element(by.label('Messagerie'))).toBeVisible();
await expect(element(by.label('Messagerie')).atIndex(0)).toBeVisible();

// Account tab
await element(by.id('tab-compte')).tap();
await expect(element(by.label('Compte'))).toBeVisible();
await expect(element(by.label('Compte')).atIndex(0)).toBeVisible();

// Home tab
await element(by.id('tab-accueil')).tap();
await expect(element(by.label('Accueil'))).toBeVisible();
await expect(element(by.label('Accueil')).atIndex(0)).toBeVisible();
});
});
8 changes: 3 additions & 5 deletions app/e2e/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ export const login = async () => {
const password = 'password';

await element(by.id('username')).clearText();
await element(by.id('username')).typeText(username);
await element(by.id('password')).typeText(password);

const loginButton = element(by.text('Se connecter'));
await loginButton.tap();
await element(by.id('username')).typeText(username + '\n');
await element(by.id('password')).typeText(password + '\n');
await element(by.text('Se connecter')).tap();
await new Promise((resolve) => setTimeout(resolve, 2000));
};
4 changes: 2 additions & 2 deletions app/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ PODS:
- React-jsinspector (0.72.6)
- React-logger (0.72.6):
- glog
- react-native-get-random-values (1.10.0):
- react-native-get-random-values (1.9.0):
- React-Core
- react-native-safe-area-context (4.6.3):
- RCT-Folly
Expand Down Expand Up @@ -750,7 +750,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 3bf18ff7cb03cd8dfdce08fbbc0d15058c1d71ae
React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072
React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289
react-native-get-random-values: 384787fd76976f5aec9465aff6fa9e9129af1e74
react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
react-native-safe-area-context: 36cc67648134e89465663b8172336a19eeda493d
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
React-NativeModulesApple: 02e35e9a51e10c6422f04f5e4076a7c02243fff2
Expand Down
87 changes: 47 additions & 40 deletions app/src/screens/guest/LoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { useAuth } from '@/hooks/useAuth';
import { useMutation } from '@apollo/client';
import LOGIN_USER from '@/graphql/mutations/auth/login-mutation';
import { KeyboardAvoidingView, Platform } from 'react-native';

const loginSchema = z.object({
username: z.string().min(1, { message: 'Champs obligatoire' }),
Expand Down Expand Up @@ -48,50 +49,56 @@ const LoginScreen: FC = () => {
};

return (
<Stack
backgroundColor="$secondary"
alignContent="center"
justifyContent="center"
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<Stack justifyContent="center" alignItems="center" height="100%">
<Stack>
<Image style={{ alignSelf: 'center' }} source={Logo} />
<Stack
width={getSizeInPixel(70)}
alignSelf="center"
marginTop={40}
rowGap={15}
>
{error && error.message && (
<Text color="$error" fontWeight="bold" testID="loginError">
{error.message}
</Text>
)}
<InputField
control={control}
name="username"
label="Pseudo ou email"
error={errors.username}
/>
<InputField
control={control}
name="password"
label="Mot de passe"
error={errors.password}
secureTextEntry
/>
<Button onPress={handleSubmit(onSubmit)} variant="primary">
{loading ? 'Chargement...' : 'Se connecter'}
</Button>
<Stack
backgroundColor="$secondary"
alignContent="center"
justifyContent="center"
>
<Stack justifyContent="center" alignItems="center" height="100%">
<Stack>
<Image style={{ alignSelf: 'center' }} source={Logo} />
<Stack
width={getSizeInPixel(70)}
alignSelf="center"
marginTop={40}
rowGap={15}
>
{error && error.message && (
<Text color="$error" fontWeight="bold" testID="loginError">
{error.message}
</Text>
)}
<InputField
control={control}
name="username"
label="Pseudo ou email"
error={errors.username}
/>
<InputField
control={control}
name="password"
label="Mot de passe"
error={errors.password}
secureTextEntry
/>
<Button onPress={handleSubmit(onSubmit)} variant="primary">
{loading ? 'Chargement...' : 'Se connecter'}
</Button>
</Stack>
</Stack>
<Stack position="absolute" bottom={50}>
<Text color="$white" textAlign="center">
Pas encore de compte ?{' '}
<Link to="Inscription">Inscrivez-vous</Link>
</Text>
</Stack>
</Stack>
<Stack position="absolute" bottom={50}>
<Text color="$white" textAlign="center">
Pas encore de compte ? <Link to="Inscription">Inscrivez-vous</Link>
</Text>
</Stack>
</Stack>
</Stack>
</KeyboardAvoidingView>
);
};

Expand Down
Loading