Skip to content

Commit

Permalink
Merge pull request #1840 from coopcycle/feature/1807-autorefresh-tasks
Browse files Browse the repository at this point in the history
autorefresh tasks for a courier
  • Loading branch information
vladimir-8 authored Aug 12, 2024
2 parents ebbcb77 + 726ddc5 commit 89c1f31
Show file tree
Hide file tree
Showing 22 changed files with 636 additions and 195 deletions.
6 changes: 3 additions & 3 deletions .detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ module.exports = {
binaryPath:
'android/app/build/outputs/apk/official/release/app-official-release.apk',
build:
'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release -DuseDebugCertificate=yes -DminifyEnabled=no -DuploadCrashlyticsMappingFile=no --warning-mode all && cd ..',
'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release -DuseDebugCertificate=yes -DminifyEnabled=no -DuploadCrashlyticsMappingFile=no --no-daemon --warning-mode all && cd ..',
launchArgs: {},
},
},
devices: {
iosSimulator: {
type: 'ios.simulator',
device: { type: 'iPhone 15', os: 'iOS 17.4' },
device: { type: 'iPhone 15', os: 'iOS 17.5' },
},
androidEmulator: {
type: 'android.emulator',
device: { avdName: 'Pixel_8_API_34' },
device: { avdName: 'Pixel_6_API_28' },
},
attached: {
type: 'android.attached',
Expand Down
68 changes: 62 additions & 6 deletions .github/workflows/testOnDevice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ jobs:
if: github.actor != 'dependabot[bot]'
name: Android Emulator Tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: coopcycle-app
env:
GEOCODE_EARTH_API_KEY: ${{ secrets.GEOCODE_EARTH_API_KEY }}
STRIPE_PUBLISHABLE_KEY: ${{ secrets.STRIPE_PUBLISHABLE_KEY }}
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
STRIPE_CONNECT_CLIENT_ID: ${{ secrets.STRIPE_CONNECT_CLIENT_ID }}
AWS_ENDPOINT: ${{ secrets.AWS_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
strategy:
# Allow tests to continue on other devices if they fail on one device.
fail-fast: false
Expand All @@ -125,21 +136,65 @@ jobs:
- 28
# - 33
steps:
# setup local coopcycle-web instance; FIXME: disabled for now as it's not enough space to run both; android build fails with 'No space left on device.'
# - uses: actions/checkout@v3
# with:
# repository: coopcycle/coopcycle-web
# path: coopcycle-web
# - name: Create .env file
# run: cp .env.dist .env
# working-directory: coopcycle-web
# - name: Pull Docker images
# run: docker compose pull --ignore-pull-failures
# working-directory: coopcycle-web
# - name: Prepare OSRM data
# run: |
# docker compose run -T --rm osrm wget --no-check-certificate https://coopcycle-assets.sfo2.digitaloceanspaces.com/osm/paris-france.osm.pbf -O /data/data.osm.pbf
# docker compose run -T --rm osrm osrm-extract -p /opt/bicycle.lua /data/data.osm.pbf
# docker compose run -T --rm osrm osrm-partition /data/data.osrm
# docker compose run -T --rm osrm osrm-customize /data/data.osrm
# working-directory: coopcycle-web
# # Cypress GitHub Action uses npm ci, and it causes a "permission denied" error,
# # because it tries to remove the node_modules/ folder, which is mounted with root:root
# # We create the node_modules/ folder *BEFORE* starting the containers,
# # so that it can be removed without problems.
# - name: Create node_modules directory
# run: mkdir node_modules
# working-directory: coopcycle-web
# - name: Start Docker containers
# run: docker compose up -d
# working-directory: coopcycle-web
# - name: Wait for PHP-FPM
# run: until docker inspect --format='{{ .State.Health.Status }}' $(docker compose ps -q php) | grep -wq healthy; do sleep 5; done
# working-directory: coopcycle-web
# - name: Create database
# run: docker compose exec -T php bin/console doctrine:schema:create --env=test
# working-directory: coopcycle-web
# - name: Create typesense collections
# run: docker compose exec -T php bin/console typesense:create --env=test
# working-directory: coopcycle-web
# - name: Setup CoopCycle
# run: docker compose exec -T php bin/console coopcycle:setup --env=test
# working-directory: coopcycle-web

- uses: actions/checkout@v3
with:
path: coopcycle-app

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
# https://github.com/jlumbroso/free-disk-space?tab=readme-ov-file#example
android: false
# large-packages: true
# swap-storage: true

- uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'yarn'
# Temporary disable yarn caching
# cache: 'yarn'
# cache-dependency-path: "coopcycle-app"

- uses: actions/setup-java@v3
with:
Expand All @@ -150,7 +205,7 @@ jobs:
- name: Decode sentry.properties file
uses: timheuer/[email protected]
with:
fileDir: "./android/"
fileDir: "./coopcycle-app/android/"
fileName: "sentry.properties"
encodedString: ${{ secrets.SENTRY_PROPERTIES_BASE64 }}

Expand Down Expand Up @@ -208,6 +263,7 @@ jobs:
run: node node_modules/.bin/detox build -c android.emu.release
env:
googleMapsApiKey: ${{ secrets.googleMapsApiKey }}
SENTRY_DISABLE_AUTO_UPLOAD: true

- name: Disk usage (filesystem)
run: df -h
Expand All @@ -227,8 +283,8 @@ jobs:
disable-animations: true
script: |
node node_modules/.bin/detox test -c android.emu.release --device-name="test" -l debug
# node node_modules/.bin/detox test -c android.att.release --device-name="test" --take-screenshots all
# node node_modules/.bin/detox test -c android.att.release --device-name="test" --take-screenshots manual -o e2e/screenshots.config.json
# node node_modules/.bin/detox test -c android.att.release --device-name="test" --take-screenshots all
# node node_modules/.bin/detox test -c android.att.release --device-name="test" --take-screenshots manual -o e2e/screenshots.config.json

- name: List supported devices
if: false # useful only for debugging
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ yarn ios
Testing
-------

```
```sh
yarn test
```

Expand All @@ -131,15 +131,21 @@ Build the app and run tests:

Android:

```
```sh
detox build -c android.emu.debug
```

```sh
detox test -c android.emu.debug
```

iOS:

```
```sh
detox build -c ios.sim.debug
```

```sh
detox test -c ios.sim.debug
```

Expand Down
1 change: 1 addition & 0 deletions e2e/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
afterAll: true,
beforeAll: true,
beforeEach: true,
expect: true,
by: true,
device: true,
element: true,
Expand Down
46 changes: 46 additions & 0 deletions e2e/02_courier.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
authenticateWithCredentials,
connectToTestInstance,
symfonyConsole,
} from './utils';

const execSync = require('child_process').execSync;

//FIXME; this test requires a local coopcycle-web instance, which is problematic to setup on CI (see testOnDevice.yml)
describe.skip('Courier', () => {
beforeEach(async () => {
symfonyConsole('coopcycle:fixtures:load -f cypress/fixtures/courier.yml');

if (device.getPlatform() === 'ios') {
// disable password autofill: https://github.com/wix/Detox/issues/3761
execSync(
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles/Library/ConfigurationProfiles/UserSettings.plist`,
);
execSync(
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Library/UserConfigurationProfiles/EffectiveUserSettings.plist`,
);
execSync(
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Library/UserConfigurationProfiles/PublicInfo/PublicEffectiveUserSettings.plist`,
);
}
await device.reloadReactNative();
await connectToTestInstance();
});

it(`should be able to login and see tasks`, async () => {
await authenticateWithCredentials('jane', '12345678');

if (device.getPlatform() === 'android') {
// dismiss BACKGROUND_PERMISSION_DISCLOSURE alert
await element(by.text('CLOSE')).tap();
}

await expect(element(by.id('messengerTabMap'))).toBeVisible();
await expect(element(by.id('messengerTabList'))).toBeVisible();

await element(by.id('messengerTabList')).tap();

await expect(element(by.id('task:0'))).toBeVisible();
await expect(element(by.id('task:1'))).toBeVisible();
});
});
50 changes: 50 additions & 0 deletions e2e/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
const execSync = require('child_process').execSync;
const os = require('os');

export const COMMAND_PREFIX = "cd ../coopcycle-web && docker compose exec -T php"

export const symfonyConsole = (command) => {
const prefix = COMMAND_PREFIX
let cmd = `bin/console ${ command } --env="test"`
if (prefix) {
cmd = `${ prefix } ${ cmd }`
}
execSync(cmd)
}

export const connectToDemo = async () => {
await expect(element(by.id('chooseCityBtn'))).toBeVisible();
await element(by.id('chooseCityBtn')).tap();
Expand All @@ -14,10 +28,46 @@ export const connectToDemo = async () => {
} catch (e) {}
};

const getLocalIpAddress = () => {
const interfaces = os.networkInterfaces();
for (const name of Object.keys(interfaces)) {
for (const iface of interfaces[name]) {
if (iface.family === 'IPv4' && !iface.internal) {
return iface.address;
}
}
}
return null;
};

export const connectToTestInstance = async () => {
await expect(element(by.id('chooseCityBtn'))).toBeVisible();
await element(by.id('chooseCityBtn')).tap();

await expect(element(by.id('moreServerOptions'))).toBeVisible();
await element(by.id('moreServerOptions')).tap();

await element(by.id('customServerURL')).typeText(`${getLocalIpAddress()}:9080\n`);

try {
// We deliberately add "\n" to hide the keyboard
// The tap below shouldn't be necessary
await element(by.id('submitCustomServer')).tap();
} catch (e) {}
};

export const authenticateWithCredentials = async (username, password) => {
await expect(element(by.id('menuBtn'))).toBeVisible();
await element(by.id('menuBtn')).tap();

await element(by.id('drawerAccountBtn')).tap();
//FIXME: for some reason drawer menu does not close after the first tap on Android
if (device.getPlatform() === 'android') {
const attrs = await element(by.id('drawerAccountBtn')).getAttributes()
if (attrs.visible) {
await element(by.id('drawerAccountBtn')).tap();
}
}

await element(by.id('loginUsername')).typeText(`${username}\n`);
await element(by.id('loginPassword')).typeText(`${password}\n`);
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ SPEC CHECKSUMS:
StripePaymentSheet: a25d920bb3bb5e2580696476482dc7df9cb5e4e2
StripePaymentsUI: 66088abec88754bbdd522ef227dfdbb2265a653e
StripeUICore: b193c7d35e9cd1b04bc9ed4a6fb8c548fcee83fa
Yoga: 9e6a04eacbd94f97d94577017e9f23b3ab41cf6c
Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5

PODFILE CHECKSUM: d949c9fd9c4ce5f3ec67d52ca1f4a1ca13072560
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@tabler/icons-react-native": "^3.2.0",
"@turf/turf": "^6.5.0",
"abortcontroller-polyfill": "^1.7.5",
"async-mutex": "^0.5.0",
"axios": "^1.6.8",
"buffer": "^6.0.3",
"centrifuge": "^2.8.4",
Expand Down
Loading

0 comments on commit 89c1f31

Please sign in to comment.