Skip to content

Commit

Permalink
internet reader e2e tests
Browse files Browse the repository at this point in the history
internet reader e2e fixes

fix typo

fix e2e tests

tests fixes and improvements

setReadDisplay/clearReaderDisplay e2e test

run setReaderDisplay e2e only on iOS

fix setReaderDisplay test

fix setReaderDisplay scenario

fix test

fix e2e test

improve reader display screen layout

prettier/eslint js files (#172)

* updates

* updates linting settings, adds prettier target

* npm reg

removed tvos target (#179)

templates (#181)

yarn diff check (#180)

* add manual yarn.lock diff check

* force fail

* how about this

* and this

* restore lockfile

Create expo plugin (#113)

* chore: create expo plugin

* chore: add plugin params

* chore: add expo docs

* fix package.json path

upgrade tsc and clean up example app routing param types (#185)

* upgrade tsc

* clean up routing param types

fix: TextInput color on Android (#84)

npm release script (#87)

* chore: add publish script

* chore: update docs

test connection token on init (#177)

* chore: test connection token on init

* chore: render app conditionally

Handle other Android connection methods (#111)

* chore: handle other connection methods

* chore: add proper e2e tests

* fix: e2e tests

* fix: e2e test

* fix indentations

* fix methods params

* fix merge issues

Revert "Handle other Android connection methods (#111)" (#186)

This reverts commit 18db810.

fix dependabot minimist issue (#189)

usb connection type (#188)

upgrade minimist in example app as well (#190)

duplicated event listeners (#182)

* fix: duplicated event listeners

* temporary listener fix

* fix typings

* cleanup

* fix updateing callbacks refs

fix labels

handle multiple secret keys, in-person refund tests

updated android sdk to 2.7.1 (#200)

Android validation and transformation helpers (#192)

* making use of new transformation functions

* validation helpers

* removed some mappers

Handle other Android connection methods #111 (#187)

* chore: handle other connection methods

* chore: add proper e2e tests

* fix: e2e tests

* fix: e2e test

* fix methods params

* rebase fixes

* rebase fix

Co-authored-by: David Henry <dhenry@stripe.com>

StripeTerminalReactNativeModule reduced scope (#202)

* separated callbacks and listeners from RN module

* cancelOperation added

* ReactNativeConstants imports

* extracting reader.serialNumber

[wip] update readme with expo guidance and re-order content (#206)

* update readme with expo guidance and re-order content

* more

* shufflin things

* toc

more doc fixes (#207)

* more fixes

* refactor

* add note about links not being available

adding codeowners (#208)

[WIP] Android unit tests (#204)

* separated callbacks and listeners from RN module

* TokenProvider unit tests

* run unit tests in circleci

* unit test yarn command

* BluetoothReaderListener unit tests

* store test results

* DiscoveryListener unit tests

* updated test output path

* test results path updated

* UsbListenerTest

* TerminalListener and HandoffReaderListener unit tests

* one more try with the test output path

Bump plist from 3.0.4 to 3.0.5 (#216)

Bumps [plist](https://github.com/TooTallNate/node-plist) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/TooTallNate/node-plist/releases)
- [Changelog](https://github.com/TooTallNate/plist.js/blob/master/History.md)
- [Commits](https://github.com/TooTallNate/node-plist/commits)

---
updated-dependencies:
- dependency-name: plist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump ansi-regex from 4.1.0 to 4.1.1 (#215)

Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](chalk/ansi-regex@v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump ansi-regex from 4.1.0 to 4.1.1 in /example (#213)

Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](chalk/ansi-regex@v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Bump plist from 3.0.4 to 3.0.5 in /example (#214)

Bumps [plist](https://github.com/TooTallNate/node-plist) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/TooTallNate/node-plist/releases)
- [Changelog](https://github.com/TooTallNate/plist.js/blob/master/History.md)
- [Commits](https://github.com/TooTallNate/node-plist/commits)

---
updated-dependencies:
- dependency-name: plist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Reader update errors received by RN SDK (#217)

* reader update errors received by RN SDK

* lint

* ios SDK sends update errors to RN SDK

Prevent from calling methods before SDK initializing SDK (#203)

* prevent from calling methods before SDK initializing SDK

* improve error message

* isInitialized as a util function

Memoize StripeTerminalProvider values (#221)

* fixing hooks deps

* fix android all target

* pushing looping location check

* memoize context

* discover

* rrc

* setupIntents

android permissions util (#218)

* android permissions util

* improve location permission message

add android expo steps to readme (#210)

* add android steps

* shuffle

* update both files

* toc

test tokenProvider on init (#211)

* test tokenProvider on init

* catchable tokenProvider error

Revert "Prevent from calling methods before SDK initializing SDK (#203)" (#225)

This reverts commit 38972ad.

added metadata property to enable Android SDK RN identification (#227)

rename e2e file

patch package

revert API_URL

handle CA server

fix commands

script rename

fix server:ci command

use canada API url from env

fix server endpoint

fix createPaymentIntent via server

Add android expo support and permissions checker (#224)

* update perms helper

* it works

* docs

* refactor permissions utils

logLevel only on StripeTerminalProvider component level (#223)

* logLevel only on StripeTerminalProvider component level

* fix typo

createPaymentIntent uses INTERAC_PRESENT for CAD currency (#232)

* createPaymentIntent uses INTERAC_PRESENT for CAD currency

* createPaymentIntent receives paymentMethodTypes from the POS application

* enum mapping fix

add setSimulatedCard method

clean up

use bluetooth reader for collecting CA payments

fix e2e tests

use keyboard aware scroll view

fix linter

set unique testID

fix tests

fix in-person refund e2e

scroll to bottom before tap

fix log name

fetch latest interac charge

refund - set test card number

fix refund e2e

fix e2e

fix android ui

fix e2e test, record failing tests

prevent call methods being not initialized (#228)

* prevent from calling methods before SDK initializing SDK

* improve error message

* isInitialized as a util function

* improvements

* remove direct functions export

implement onDidReportAvailableUpdate in example app (#236)

enable interac for e2e android scenario

skip refunding tests on android

fix e2e test

add comments
  • Loading branch information
arekkubaczkowski authored and jdivock-stripe committed Apr 6, 2022
1 parent 1cec642 commit 28c305b
Show file tree
Hide file tree
Showing 26 changed files with 714 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ package com.stripeterminalreactnative
import android.app.Application
import android.content.ComponentCallbacks2
import android.content.res.Configuration
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.bridge.WritableNativeArray
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
import com.facebook.react.bridge.*
import com.stripe.stripeterminal.Terminal
import com.stripe.stripeterminal.TerminalApplicationDelegate.onCreate
import com.stripe.stripeterminal.TerminalApplicationDelegate.onTrimMemory
Expand Down Expand Up @@ -119,6 +111,16 @@ class StripeTerminalReactNativeModule(reactContext: ReactApplicationContext) :
promise.resolve(WritableNativeMap())
}

@ReactMethod
@Suppress("unused")
fun setSimulatedCard(cardNumber: String, promise: Promise) {
terminal.simulatorConfiguration = SimulatorConfiguration(
terminal.simulatorConfiguration.update,
SimulatedCard(testCardNumber = cardNumber)
)
promise.resolve(WritableNativeMap())
}

@ReactMethod
@Suppress("unused")
fun setConnectionToken(params: ReadableMap, promise: Promise) {
Expand Down Expand Up @@ -172,9 +174,7 @@ class StripeTerminalReactNativeModule(reactContext: ReactApplicationContext) :
"Could not find a reader with serialNumber $serialNumber"
}

val locationId = requireParam(params.getString("locationId") ?: selectedReader.location?.id) {
"You must provide a locationId"
}
val locationId = params.getString("locationId") ?: selectedReader.location?.id.orEmpty()

CoroutineScope(Dispatchers.IO).launch {
val connectedReader =
Expand Down
10 changes: 6 additions & 4 deletions e2e/app.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const { cleanPaymentMethods } = require('./clean');

jest.retryTimes(3);

describe('Payments', () => {
describe('Basic funtionalities', () => {
beforeAll(async () => {
await cleanPaymentMethods();
});
Expand Down Expand Up @@ -188,14 +188,16 @@ describe('Payments', () => {

await navigateTo('In-Person Refund');

const chargeIdInout = element(by.id('charge-id-text-field'));
const chargeIdInput = element(by.id('charge-id-text-field'));
const amountInput = element(by.id('amount-text-field'));

await waitFor(chargeIdInout).toBeVisible().withTimeout(16000);
await waitFor(chargeIdInput).toBeVisible().withTimeout(16000);
await waitFor(amountInput).toBeVisible();

await amountInput.replaceText('20000');
await chargeIdInout.replaceText('ch_3JxsjUBDuqlYGNW21EL8UyOm');
await chargeIdInput.replaceText('ch_3JxsjUBDuqlYGNW21EL8UyOm');

await element(by.id('refund-scroll-view')).scrollTo('bottom');

const button = element(by.id('collect-refund-button'));

Expand Down
149 changes: 149 additions & 0 deletions e2e/in-person-refund.e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* eslint-env detox/detox, jest */

const {
navigateTo,
connectReader,
checkIfLogExist,
checkIfConnected,
changeDiscoveryMethod,
} = require('./utils');

jest.retryTimes(3);

describe('In-Person Refund', () => {
beforeEach(async () => {
await device.launchApp({
permissions: { location: 'always' },
launchArgs: {
canada: true,
},
newInstance: true,
});
});

afterAll(async () => {
await device.sendToHome();
});

it('Collect CA card payment', async () => {
await navigateTo('Discover Readers');
await connectReader('wisePad3');

await navigateTo('Collect card payment');

const currencyInput = element(by.id('currency-text-field'));
const amountInput = element(by.id('amount-text-field'));
const cardNumberInput = element(by.id('card-number-text-field'));

await waitFor(currencyInput).toBeVisible().withTimeout(16000);
await waitFor(amountInput).toBeVisible().withTimeout(10000);
await waitFor(cardNumberInput).toBeVisible().withTimeout(10000);

const enableInteracSwitch = element(by.id('enable-interac'));
await waitFor(enableInteracSwitch).toBeVisible().withTimeout(10000);
await enableInteracSwitch.tap();

await amountInput.replaceText('20000');
await currencyInput.replaceText('CAD');

// set interac test card
await cardNumberInput.replaceText('4506445006931933');

await element(by.id('collect-scroll-view')).scrollTo('bottom');

const capturePaymentIntentSwitch = element(by.id('capture-payment-intent'));
await waitFor(capturePaymentIntentSwitch).toBeVisible().withTimeout(10000);
// do not capture PI because this specific card number captures it automatically.
await capturePaymentIntentSwitch.tap();

await element(by.id('collect-scroll-view')).scrollTo('bottom');

const button = element(by.text('Collect payment'));

await waitFor(button).toBeVisible().withTimeout(10000);

await button.tap();

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Create');
await checkIfLogExist('Created');
await checkIfLogExist('Collect');
await checkIfLogExist('Collected');
await checkIfLogExist('Process');
await checkIfLogExist('Processed');
});

it('via bluetooth reader', async () => {
// Temporary skipped on Android due to some issues with refunding payments
if (device.getPlatform() === 'android') {
return;
}
await navigateTo('Discover Readers');
await connectReader('wisePad3');

await checkIfConnected({ device: 'wisePad3' });
await element(by.id('home-screen')).scrollTo('bottom');

await navigateTo('In-Person Refund');

const amountInput = element(by.id('amount-text-field'));
await waitFor(amountInput).toBeVisible();

await amountInput.replaceText('100');

await element(by.id('refund-scroll-view')).scrollTo('bottom');

const button = element(by.id('collect-refund-button'));

await waitFor(button).toBeVisible();

await button.tap();

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Collect');
await checkIfLogExist('Collected');
await checkIfLogExist('Processing');
await checkIfLogExist('Succeeded');
});

it('via internet reader', async () => {
// Temporary skipped on Android due to some issues with refunding payments
if (device.getPlatform() === 'android') {
return;
}

await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader('verifoneP400');

await checkIfConnected({ device: 'verifoneP400' });
await element(by.id('home-screen')).scrollTo('bottom');

await navigateTo('In-Person Refund');

const amountInput = element(by.id('amount-text-field'));
await waitFor(amountInput).toBeVisible();

await amountInput.replaceText('100');

await element(by.id('refund-scroll-view')).scrollTo('bottom');

const button = element(by.id('collect-refund-button'));

await waitFor(button).toBeVisible();

await button.tap();

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Collect');
await checkIfLogExist('Collected');
await checkIfLogExist('Processing');
await checkIfLogExist('Succeeded');
});
});
147 changes: 147 additions & 0 deletions e2e/internet-reader.e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* eslint-env detox/detox, jest */

const {
navigateTo,
connectReader,
checkIfLogExist,
checkIfConnected,
changeDiscoveryMethod,
} = require('./utils');

const { cleanPaymentMethods } = require('./clean');

jest.retryTimes(3);

describe('Internet reader', () => {
beforeAll(async () => {
await cleanPaymentMethods();
});

beforeEach(async () => {
await device.launchApp({
permissions: { location: 'always' },
newInstance: true,
});
});

afterAll(async () => {
await device.sendToHome();
});

it('Connect and disconnect', async () => {
await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader('verifoneP400');
await checkIfConnected({ device: 'verifoneP400' });
});

it('Collect card payment', async () => {
await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader('verifoneP400');

await navigateTo('Collect card payment');

const currencyInput = element(by.id('currency-text-field'));
const amountInput = element(by.id('amount-text-field'));

await waitFor(currencyInput).toBeVisible().withTimeout(16000);
await waitFor(amountInput).toBeVisible();

await amountInput.replaceText('20000');
await currencyInput.replaceText('USD');

await element(by.id('collect-scroll-view')).scrollTo('bottom');

const button = element(by.text('Collect payment'));

await waitFor(button).toBeVisible();

await button.tap();

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Create');
await checkIfLogExist('Created');
await checkIfLogExist('Collect');
await checkIfLogExist('Collected');
await checkIfLogExist('Process');
await checkIfLogExist('Processed');
await checkIfLogExist('Capture');
await checkIfLogExist('Captured');
});

it('Store card via readReusableCard', async () => {
await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader('verifoneP400');

await navigateTo('Store card via readReusableCard');

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Start');
await checkIfLogExist('Finished');
});

it('Store card via SetupIntent', async () => {
// Store card via SetupIntent is not available for verifoneP400 on iOS
// while this is the only available simulated reader on Android
const readerName =
device.getPlatform() === 'ios' ? 'wisePosE' : 'verifoneP400';
await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader(readerName);

await checkIfConnected({ device: readerName });
await element(by.id('home-screen')).scrollTo('bottom');

await navigateTo('Store card via Setup Intents');

const eventLogTitle = element(by.text('EVENT LOG'));
await waitFor(eventLogTitle).toBeVisible().withTimeout(16000);

await checkIfLogExist('Create');
await checkIfLogExist('Collect');
await checkIfLogExist('Created');
await checkIfLogExist('Process');
await checkIfLogExist('Finished');
});

it('setReaderDisplay/clearReaderDisplay', async () => {
// The only available verifoneP400 reader doesn't support setReaderDisplay funtionality in simulated mode.
if (device.getPlatform() === 'android') {
return;
}
await changeDiscoveryMethod('Internet');
await navigateTo('Discover Readers');
await connectReader('verifoneP400');

await checkIfConnected({ device: 'verifoneP400' });
await element(by.id('home-screen')).scrollTo('bottom');

await navigateTo('Set reader display');

const setButton = element(by.id('set-reader-display'));
await waitFor(setButton).toBeVisible().withTimeout(10000);
await setButton.tap();

await waitFor(element(by.text('setReaderDisplay success')))
.toBeVisible()
.withTimeout(16000);

const confirmAlertButton = element(by.text('OK'));
await waitFor(confirmAlertButton).toBeVisible();
await confirmAlertButton.tap();

const clearButton = element(by.id('clear-reader-display'));
await waitFor(clearButton).toBeVisible().withTimeout(10000);
await clearButton.tap();

await waitFor(element(by.text('clearReaderDisplay success')))
.toBeVisible()
.withTimeout(16000);
});
});
Loading

0 comments on commit 28c305b

Please sign in to comment.