From fb8a6de721559d91b768183785ad5567456a7934 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 14:11:50 +0200 Subject: [PATCH 01/12] Add karate ui event rollcall tests --- .../rollCall/components/AttendeeList.tsx | 4 +- .../rollCall/components/RollCallOpen.tsx | 4 +- .../test/java/common/utils/MockClient.java | 74 +++++++++++++++++++ .../src/test/java/fe/features/event.feature | 31 ++++++++ .../src/test/java/fe/features/lao.feature | 9 +-- .../src/test/java/fe/utils/android.feature | 8 ++ .../src/test/java/fe/utils/constants.feature | 1 + .../karate/src/test/java/fe/utils/web.feature | 16 ++++ 8 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 tests/karate/src/test/java/fe/features/event.feature diff --git a/fe1-web/src/features/rollCall/components/AttendeeList.tsx b/fe1-web/src/features/rollCall/components/AttendeeList.tsx index 80da1c34e3..bc448f1c06 100644 --- a/fe1-web/src/features/rollCall/components/AttendeeList.tsx +++ b/fe1-web/src/features/rollCall/components/AttendeeList.tsx @@ -70,7 +70,9 @@ const AttendeeList = ({ popTokens, personalToken }: IPropTypes) => { + testID={`attendee_${idx}`} + selectable + > {token.valueOf()} diff --git a/fe1-web/src/features/rollCall/components/RollCallOpen.tsx b/fe1-web/src/features/rollCall/components/RollCallOpen.tsx index df5df0a24d..e6a6d14692 100644 --- a/fe1-web/src/features/rollCall/components/RollCallOpen.tsx +++ b/fe1-web/src/features/rollCall/components/RollCallOpen.tsx @@ -196,7 +196,9 @@ const RollCallOpen = ({ Typography.centered, Typography.code, textStyle.topSpace, - ]}> + ]} + testID='roll_call_pop_token' + > {popToken} Clipboard.setStringAsync(popToken)}> diff --git a/tests/karate/src/test/java/common/utils/MockClient.java b/tests/karate/src/test/java/common/utils/MockClient.java index 247c7a7c3f..de05233ec9 100644 --- a/tests/karate/src/test/java/common/utils/MockClient.java +++ b/tests/karate/src/test/java/common/utils/MockClient.java @@ -122,4 +122,78 @@ public Lao createLao(Lao lao) { return lao; } + + /** + * Creates a roll call. + * @param lao the lao to create the roll call for + * @return the roll call created + */ + public RollCall createRollCall(Lao lao) { + RollCall rollCall = generateValidRollCall(lao); + return createRollCall(lao, rollCall); + } + + /** + * Creates a roll call. + * @param lao the lao to create the roll call for + * @param rollCall the roll call to create + * @return the roll call passed as argument + */ + public RollCall createRollCall(Lao lao, RollCall rollCall) { + Map request = new HashMap<>(); + request.put("object", "roll_call"); + request.put("action", "create"); + request.put("id", rollCall.id); + request.put("name", rollCall.name); + request.put("creation", rollCall.creation); + request.put("proposed_start", rollCall.start); + request.put("proposed_end", rollCall.end); + request.put("location", rollCall.location); + request.put("description", rollCall.description); + + this.publish(request, lao.channel); + this.getBackendResponse(request); + + return rollCall; + } + + /** + * Opens a roll call. + * @param lao the lao the roll call belongs to + * @param rollCall the roll call to open + */ + public void openRollCall(Lao lao, RollCall rollCall) { + RollCall.RollCallOpen openRollCall = rollCall.open(); + + Map request = new HashMap<>(); + request.put("object", "roll_call"); + request.put("action", "open"); + request.put("update_id", openRollCall.updateId); + request.put("opens", openRollCall.opens); + request.put("opened_at", openRollCall.openedAt); + + this.publish(request, lao.channel); + this.getBackendResponse(request); + } + + /** + * Closes a roll call. + * @param lao the lao the roll call belongs to + * @param rollCall the roll call to close + */ + public void closeRollCall(Lao lao, RollCall rollCall, List attendees) { + RollCall.RollCallClose closeRollCall = rollCall.close(); + + Map request = new HashMap<>(); + request.put("object", "roll_call"); + request.put("action", "close"); + request.put("update_id", closeRollCall.updateId); + request.put("closes", closeRollCall.closes); + request.put("closed_at", closeRollCall.closedAt); + request.put("attendees", attendees); + + + this.publish(request, lao.channel); + this.getBackendResponse(request); + } } diff --git a/tests/karate/src/test/java/fe/features/event.feature b/tests/karate/src/test/java/fe/features/event.feature new file mode 100644 index 0000000000..8634b0dbcf --- /dev/null +++ b/tests/karate/src/test/java/fe/features/event.feature @@ -0,0 +1,31 @@ +Feature: Event + Background: + * call read('classpath:fe/utils/constants.feature') + * call read(MOCK_CLIENT_FEATURE) + + @name=event_create_rollcall + Scenario: + Given call read(PLATFORM_FEATURE) { name: '#(CREATE_LAO)', params: { organization_name: 'Create Roll-Call Org' } } + And def rollCallName = 'My Roll-Call' + When waitFor(event_create_button).click() + And actionSheetClick(event_create_rollcall) + And waitFor(event_rollcall_name_input).input(rollCallName) + And waitFor(event_rollcall_location_input).input('Between 1 and 0s') + And waitFor(event_rollcall_confirm_button).click() + Then waitForText(event_first_current_event, rollCallName) + And screenshot() + + @name=event_join_rollcall + Scenario: + Given def organizer = createMockClient() + And def lao = organizer.createLao() + And def rollCall = organizer.createRollCall(lao) + And organizer.openRollCall(lao, rollCall) + And call read(PLATFORM_FEATURE) { name: '#(JOIN_LAO)', params: { lao: '#(lao)' } } + When waitFor(event_first_current_event).click() + And waitFor(event_rollcall_pop_token) + And delay(1000) + And def popToken = text(event_rollcall_pop_token) + And organizer.closeRollCall(lao, rollCall, [popToken]) + Then waitForText(event_rollcall_first_attendee, popToken) + And screenshot() diff --git a/tests/karate/src/test/java/fe/features/lao.feature b/tests/karate/src/test/java/fe/features/lao.feature index 20fc65cd3e..ae72adc5c1 100644 --- a/tests/karate/src/test/java/fe/features/lao.feature +++ b/tests/karate/src/test/java/fe/features/lao.feature @@ -5,13 +5,8 @@ Feature: LAO @name=lao_create Scenario: Create a new LAO - Given call read(PLATFORM_FEATURE) { name: '#(CREATE_NEW_WALLET)' } - And def organization_name = 'My test organization' - When waitFor(lao_create_button).click() - And waitFor(lao_organization_name_input).input(organization_name) - And waitFor(lao_server_url_input).clear().input(serverURL) - And click(lao_launch_button) - Then waitFor(event_create_button) + Given call read(PLATFORM_FEATURE) { name: '#(CREATE_LAO)', params: { organization_name: 'My test organization' } } + When waitFor(event_create_button) Then screenshot() @name=lao_join diff --git a/tests/karate/src/test/java/fe/utils/android.feature b/tests/karate/src/test/java/fe/utils/android.feature index 68fc6e7a89..164c0e2481 100644 --- a/tests/karate/src/test/java/fe/utils/android.feature +++ b/tests/karate/src/test/java/fe/utils/android.feature @@ -44,3 +44,11 @@ Feature: android page object Scenario: # Not implemented yet * assert false + + @name=lao_create + Scenario: + Given call read('android.feature@name=create_new_wallet') + When waitFor(lao_create_button).click() + And waitFor(lao_organization_name_input).input(organization_name) + And waitFor(lao_server_url_input).clear().input(serverURL) + Then click(lao_launch_button) diff --git a/tests/karate/src/test/java/fe/utils/constants.feature b/tests/karate/src/test/java/fe/utils/constants.feature index bae23bec27..a1248e89a9 100644 --- a/tests/karate/src/test/java/fe/utils/constants.feature +++ b/tests/karate/src/test/java/fe/utils/constants.feature @@ -4,6 +4,7 @@ Feature: Constants # Features * def PLATFORM_FEATURE = 'classpath:fe/utils/platform.feature' * def MOCK_CLIENT_FEATURE = 'classpath:fe/utils/mock_client.feature' + * def LAO_FEATURE = 'classpath:fe/features/lao.feature' # Wallet * def OPEN_APP = 'open_app' * def CREATE_NEW_WALLET = 'create_new_wallet' diff --git a/tests/karate/src/test/java/fe/utils/web.feature b/tests/karate/src/test/java/fe/utils/web.feature index 3520c59a3f..3fe1368985 100644 --- a/tests/karate/src/test/java/fe/utils/web.feature +++ b/tests/karate/src/test/java/fe/utils/web.feature @@ -2,6 +2,7 @@ Feature: web page object Background: # Functions + * def actionSheetClick = (text) => script("setTimeout(() => document.evaluate('//div[text()=\\'" + text + "\\']', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(), 1000)") # Wallet screen * def wallet_seed_wallet_text = "[data-testid='seed_wallet_text']" @@ -23,7 +24,14 @@ Feature: web page object # Event screen * def event_create_button = "[data-testid='create_event_selector']" + * def event_create_rollcall = "Create Roll-Call" * def event_title = "{}Events" + * def event_rollcall_name_input = "input[data-testid='roll_call_name_selector']" + * def event_rollcall_location_input = "input[data-testid='roll_call_location_selector']" + * def event_rollcall_confirm_button = "[data-testid='roll_call_confirm_selector']" + * def event_rollcall_pop_token = "div[data-testid='roll_call_pop_token']" + * def event_rollcall_first_attendee = "div[data-testid='attendee_0']" + * def event_first_current_event = "[data-testid='current_event_selector_0']" @name=open_app Scenario: @@ -54,3 +62,11 @@ Feature: web page object And waitFor(lao_enter_manually_lao_input).clear().input(params.lao.id) And click(lao_enter_manually_submit_button) Then waitFor(event_title) + + @name=lao_create + Scenario: + Given call read('web.feature@name=create_new_wallet') + When waitFor(lao_create_button).click() + And waitFor(lao_organization_name_input).input(organization_name) + And waitFor(lao_server_url_input).clear().input(serverURL) + Then click(lao_launch_button) From f068da3fcf9212187e4948372ce9cbe9399478d0 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 14:28:49 +0200 Subject: [PATCH 02/12] Add support android karate create rollcall --- tests/karate/src/test/java/fe/features/event.feature | 2 +- tests/karate/src/test/java/fe/utils/android.feature | 12 ++++++++++++ .../karate/src/test/java/fe/utils/constants.feature | 2 ++ tests/karate/src/test/java/fe/utils/web.feature | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/karate/src/test/java/fe/features/event.feature b/tests/karate/src/test/java/fe/features/event.feature index 8634b0dbcf..6e823cf587 100644 --- a/tests/karate/src/test/java/fe/features/event.feature +++ b/tests/karate/src/test/java/fe/features/event.feature @@ -8,7 +8,7 @@ Feature: Event Given call read(PLATFORM_FEATURE) { name: '#(CREATE_LAO)', params: { organization_name: 'Create Roll-Call Org' } } And def rollCallName = 'My Roll-Call' When waitFor(event_create_button).click() - And actionSheetClick(event_create_rollcall) + And call read(PLATFORM_FEATURE) { name: '#(CLICK_CREATE_ROLLCALL)' } And waitFor(event_rollcall_name_input).input(rollCallName) And waitFor(event_rollcall_location_input).input('Between 1 and 0s') And waitFor(event_rollcall_confirm_button).click() diff --git a/tests/karate/src/test/java/fe/utils/android.feature b/tests/karate/src/test/java/fe/utils/android.feature index 164c0e2481..90834a3f1b 100644 --- a/tests/karate/src/test/java/fe/utils/android.feature +++ b/tests/karate/src/test/java/fe/utils/android.feature @@ -21,6 +21,14 @@ Feature: android page object # Event screen * def event_create_button = "#com.github.dedis.popstellar:id/add_event" + * def event_create_rollcall = "#com.github.dedis.popstellar:id/add_roll_call" + * def event_title = "{}Events" + * def event_rollcall_name_input = "#com.github.dedis.popstellar:id/roll_call_title_text" + * def event_rollcall_location_input = "#com.github.dedis.popstellar:id/roll_call_event_location_text" + * def event_rollcall_confirm_button = "#com.github.dedis.popstellar:id/roll_call_confirm" + * def event_rollcall_pop_token = "div[data-testid='roll_call_pop_token']" + * def event_rollcall_first_attendee = "#android:id/text1" + * def event_first_current_event = "#com.github.dedis.popstellar:id/event_card_text_view" @name=open_app Scenario: @@ -52,3 +60,7 @@ Feature: android page object And waitFor(lao_organization_name_input).input(organization_name) And waitFor(lao_server_url_input).clear().input(serverURL) Then click(lao_launch_button) + + @name=click_rollcall_create + Scenario: + * waitFor(event_create_rollcall).click() diff --git a/tests/karate/src/test/java/fe/utils/constants.feature b/tests/karate/src/test/java/fe/utils/constants.feature index a1248e89a9..fd4d787ffe 100644 --- a/tests/karate/src/test/java/fe/utils/constants.feature +++ b/tests/karate/src/test/java/fe/utils/constants.feature @@ -12,3 +12,5 @@ Feature: Constants # Lao * def JOIN_LAO = 'lao_join' * def CREATE_LAO = 'lao_create' + # Event + * def CLICK_CREATE_ROLLCALL = 'click_rollcall_create' diff --git a/tests/karate/src/test/java/fe/utils/web.feature b/tests/karate/src/test/java/fe/utils/web.feature index 3fe1368985..b8417f1a11 100644 --- a/tests/karate/src/test/java/fe/utils/web.feature +++ b/tests/karate/src/test/java/fe/utils/web.feature @@ -70,3 +70,7 @@ Feature: web page object And waitFor(lao_organization_name_input).input(organization_name) And waitFor(lao_server_url_input).clear().input(serverURL) Then click(lao_launch_button) + + @name=click_rollcall_create + Scenario: + * actionSheetClick(event_create_rollcall) From a58eca2a7bd93da0148415eca16610af87e0dc7b Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 14:40:08 +0200 Subject: [PATCH 03/12] Update snapshot --- .../ViewSingleRollCall.test.tsx.snap | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/fe1-web/src/features/rollCall/screens/__tests__/__snapshots__/ViewSingleRollCall.test.tsx.snap b/fe1-web/src/features/rollCall/screens/__tests__/__snapshots__/ViewSingleRollCall.test.tsx.snap index f0bd4babc1..2b21c92f4e 100644 --- a/fe1-web/src/features/rollCall/screens/__tests__/__snapshots__/ViewSingleRollCall.test.tsx.snap +++ b/fe1-web/src/features/rollCall/screens/__tests__/__snapshots__/ViewSingleRollCall.test.tsx.snap @@ -512,6 +512,7 @@ exports[`EventRollCall render correctly no duplicate attendees opened roll calls }, ] } + testID="roll_call_pop_token" /> attendee1 @@ -1018,7 +1019,7 @@ exports[`EventRollCall render correctly no duplicate attendees opened roll calls "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -1555,6 +1556,7 @@ exports[`EventRollCall render correctly no duplicate attendees re-opened roll ca }, ] } + testID="roll_call_pop_token" /> attendee1 @@ -2061,7 +2063,7 @@ exports[`EventRollCall render correctly no duplicate attendees re-opened roll ca "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -2801,7 +2803,7 @@ exports[`EventRollCall render correctly non organizers closed roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_0" > attendee1 @@ -2948,7 +2950,7 @@ exports[`EventRollCall render correctly non organizers closed roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -3911,6 +3913,7 @@ exports[`EventRollCall render correctly non organizers opened roll calls 1`] = ` }, ] } + testID="roll_call_pop_token" /> attendee1 @@ -4417,7 +4420,7 @@ exports[`EventRollCall render correctly non organizers opened roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -4954,6 +4957,7 @@ exports[`EventRollCall render correctly non organizers re-opened roll calls 1`] }, ] } + testID="roll_call_pop_token" /> attendee1 @@ -5460,7 +5464,7 @@ exports[`EventRollCall render correctly non organizers re-opened roll calls 1`] "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -6200,7 +6204,7 @@ exports[`EventRollCall render correctly organizers closed roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_0" > attendee1 @@ -6347,7 +6351,7 @@ exports[`EventRollCall render correctly organizers closed roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -7645,7 +7649,7 @@ exports[`EventRollCall render correctly organizers opened roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_0" > attendee1 @@ -7792,7 +7796,7 @@ exports[`EventRollCall render correctly organizers opened roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 @@ -8656,7 +8660,7 @@ exports[`EventRollCall render correctly organizers re-opened roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_0" > attendee1 @@ -8803,7 +8807,7 @@ exports[`EventRollCall render correctly organizers re-opened roll calls 1`] = ` "textAlign": "left", } } - testID="listItemTitle" + testID="attendee_1" > attendee2 From 311508154da4d83ebe8d3a389d9a487f7361af0a Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 14:41:49 +0200 Subject: [PATCH 04/12] Lint --- fe1-web/src/features/rollCall/components/AttendeeList.tsx | 3 +-- fe1-web/src/features/rollCall/components/RollCallOpen.tsx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fe1-web/src/features/rollCall/components/AttendeeList.tsx b/fe1-web/src/features/rollCall/components/AttendeeList.tsx index bc448f1c06..aa1e88ee8b 100644 --- a/fe1-web/src/features/rollCall/components/AttendeeList.tsx +++ b/fe1-web/src/features/rollCall/components/AttendeeList.tsx @@ -71,8 +71,7 @@ const AttendeeList = ({ popTokens, personalToken }: IPropTypes) => { style={[Typography.base, Typography.code]} numberOfLines={1} testID={`attendee_${idx}`} - selectable - > + selectable> {token.valueOf()} diff --git a/fe1-web/src/features/rollCall/components/RollCallOpen.tsx b/fe1-web/src/features/rollCall/components/RollCallOpen.tsx index e6a6d14692..f74469f275 100644 --- a/fe1-web/src/features/rollCall/components/RollCallOpen.tsx +++ b/fe1-web/src/features/rollCall/components/RollCallOpen.tsx @@ -197,8 +197,7 @@ const RollCallOpen = ({ Typography.code, textStyle.topSpace, ]} - testID='roll_call_pop_token' - > + testID="roll_call_pop_token"> {popToken} Clipboard.setStringAsync(popToken)}> From 9ec0dd411081ab9b0d50f42cecd3a26d1a9f38e1 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 20:02:34 +0200 Subject: [PATCH 05/12] Update karate ui event tests for android --- .../ui/lao/event/rollcall/RollCallFragment.kt | 9 +++++++++ .../main/res/layout/roll_call_fragment.xml | 13 ++++++++++++- tests/karate/docs/README.md | 6 ++++-- .../test/java/common/utils/MockClient.java | 11 +++++++++++ .../src/test/java/fe/utils/android.feature | 19 ++++++++++++++----- tests/karate/src/test/java/karate-config.js | 4 +++- 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt index 2a809d6189..d0224241f7 100644 --- a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt +++ b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt @@ -297,6 +297,13 @@ class RollCallFragment : AbstractEventFragment { Timber.tag(TAG).d("key displayed is %s", pk) // Set the QR visible only if the rollcall is opened and the user isn't the organizer + if (rollCall.isOpen) { + binding.rollCallPkQrCode.visibility = View.VISIBLE + binding.rollCallPopTokenText.visibility = View.VISIBLE + } else { + binding.rollCallPkQrCode.visibility = View.INVISIBLE + binding.rollCallPopTokenText.visibility = View.INVISIBLE + } binding.rollCallPkQrCode.visibility = if (rollCall.isOpen) View.VISIBLE else View.INVISIBLE // Don't lose time generating the QR code if it's not visible @@ -304,6 +311,8 @@ class RollCallFragment : AbstractEventFragment { return } + binding.rollCallPopTokenText.text = pk + val data = PopTokenData(PublicKey(pk)) val myBitmap = QRCode.from(gson.toJson(data)) diff --git a/fe2-android/app/src/main/res/layout/roll_call_fragment.xml b/fe2-android/app/src/main/res/layout/roll_call_fragment.xml index d3bcade333..ab15d96463 100644 --- a/fe2-android/app/src/main/res/layout/roll_call_fragment.xml +++ b/fe2-android/app/src/main/res/layout/roll_call_fragment.xml @@ -74,6 +74,15 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/roll_call_end_time" /> + + /> + + app:layout_constraintVertical_bias="@dimen/roll_call_attendees_list_vertical_bias" > + + diff --git a/tests/karate/docs/README.md b/tests/karate/docs/README.md index 2d0b417ce0..3e64017664 100644 --- a/tests/karate/docs/README.md +++ b/tests/karate/docs/README.md @@ -221,7 +221,8 @@ The following options are available (option names must be prefixed by `-D`). | url | URL of the web app | 'file:../../fe1-web/web-build/index.html' | | screenWidth | Width of the browser | 1920 | | screenHeight | Height of the browser | 1080 | -| serverURL | Client URL of the backend server | 'ws://localhost:9000/client' for the web and 'ws://10.0.2.2:9000/client' for android | +| serverURL | Client URL of the backend server from the test host perspective | 'ws://localhost:9000/client' | +| platformServerURL | Client URL of the backend server from the tested platform perspective | 'ws://localhost:9000/client' | ### Android Front-end Build the application by running `./gradlew assembleDebug` in the corresponding directory. @@ -247,4 +248,5 @@ The following options are available (option names must be prefixed by `-D`). | Name | Description | Default | |--------------|------------------------------------------------|-------------------------------------------| | avd | Name of the android emulator | Choosen automatically by appium | -| serverURL | Client URL of the backend server | 'ws://localhost:9000/client' for the web and 'ws://10.0.2.2:9000/client' for android | +| serverURL | Client URL of the backend server from the test host perspective | 'ws://localhost:9000/client' | +| platformServerURL | Client URL of the backend server from the tested platform perspective | 'ws://10.0.2.2:9000/client' | diff --git a/tests/karate/src/test/java/common/utils/MockClient.java b/tests/karate/src/test/java/common/utils/MockClient.java index de05233ec9..18c9ec6031 100644 --- a/tests/karate/src/test/java/common/utils/MockClient.java +++ b/tests/karate/src/test/java/common/utils/MockClient.java @@ -154,6 +154,17 @@ public RollCall createRollCall(Lao lao, RollCall rollCall) { this.publish(request, lao.channel); this.getBackendResponse(request); + Map sub = new HashMap<>(); + sub.put("method", "subscribe"); + sub.put("id", 2); + Map params = new HashMap<>(); + params.put("channel", lao.channel); + sub.put("params", params); + sub.put("jsonrpc", "2.0"); + + this.send(sub); + this.takeTimeout(1000); + return rollCall; } diff --git a/tests/karate/src/test/java/fe/utils/android.feature b/tests/karate/src/test/java/fe/utils/android.feature index 90834a3f1b..dc6c47ed8e 100644 --- a/tests/karate/src/test/java/fe/utils/android.feature +++ b/tests/karate/src/test/java/fe/utils/android.feature @@ -22,11 +22,11 @@ Feature: android page object # Event screen * def event_create_button = "#com.github.dedis.popstellar:id/add_event" * def event_create_rollcall = "#com.github.dedis.popstellar:id/add_roll_call" - * def event_title = "{}Events" + * def event_title = '//android.widget.TextView[@text="Events"]' * def event_rollcall_name_input = "#com.github.dedis.popstellar:id/roll_call_title_text" * def event_rollcall_location_input = "#com.github.dedis.popstellar:id/roll_call_event_location_text" * def event_rollcall_confirm_button = "#com.github.dedis.popstellar:id/roll_call_confirm" - * def event_rollcall_pop_token = "div[data-testid='roll_call_pop_token']" + * def event_rollcall_pop_token = "#com.github.dedis.popstellar:id/roll_call_pop_token_text" * def event_rollcall_first_attendee = "#android:id/text1" * def event_first_current_event = "#com.github.dedis.popstellar:id/event_card_text_view" @@ -50,15 +50,24 @@ Feature: android page object @name=lao_join Scenario: - # Not implemented yet - * assert false + Given call read('android.feature@name=create_new_wallet') + When waitFor(lao_join_button).click() + And waitFor(lao_enter_manually_button).click() + # For some reason, karate always converts json strings to javascript objects when passed as parameters to the input function. + # This workaround is the only solution I found to pass a json string as a parameter to the input field. + # This should be fixed once multiple fields are used instead of a single field accepting json. + And json jsonArray = ['{"lao":"', "#(params.lao.id)", '","server":"', "#(platformServerURL)", '"}'] + And string jsonString = jsonArray + And input(lao_enter_manually_lao_input, jsonString) + And click(lao_enter_manually_submit_button) + Then waitFor(event_title) @name=lao_create Scenario: Given call read('android.feature@name=create_new_wallet') When waitFor(lao_create_button).click() And waitFor(lao_organization_name_input).input(organization_name) - And waitFor(lao_server_url_input).clear().input(serverURL) + And waitFor(lao_server_url_input).clear().input(platformServerURL) Then click(lao_launch_button) @name=click_rollcall_create diff --git a/tests/karate/src/test/java/karate-config.js b/tests/karate/src/test/java/karate-config.js index ce370b0c96..b1dfb7a20b 100644 --- a/tests/karate/src/test/java/karate-config.js +++ b/tests/karate/src/test/java/karate-config.js @@ -34,6 +34,7 @@ function fn() { config.backendWsURL = `ws://${config.host}:${config.backendPort}/${config.backendPath}`; } else if (env === 'web') { config.serverURL = karate.properties['serverURL'] || 'ws://localhost:9000/client'; + config.platformServerURL = karate.properties['platformServerURL'] || 'ws://localhost:9000/client'; config.frontendURL = karate.properties['url'] || `file://${karate.toAbsolutePath('file:../../fe1-web/web-build/index.html')}`; config.screenWidth = karate.properties['screenWidth'] || 1920; config.screenHeight = karate.properties['screenHeight'] || 1080; @@ -98,7 +99,8 @@ function fn() { } }; } else if (env === 'android') { - config.serverURL = karate.properties['serverURL'] || 'ws://10.0.2.2:9000/client'; + config.serverURL = karate.properties['serverURL'] || 'ws://localhost:9000/client'; + config.platformServerURL = karate.properties['platformServerURL'] || 'ws://10.0.2.2:9000/client'; karate.configure('driver', { type: 'android', webDriverPath : "/", start: false }); const app = karate.properties['app'] || '../../fe2-android/app/build/outputs/apk/debug/app-debug.apk'; config.webDriverOptions = { From 7e58d35fe1e177d064942f2d90249f886ab5a3a1 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 20:27:34 +0200 Subject: [PATCH 06/12] Add android tests --- .../src/main/res/layout/roll_call_fragment.xml | 1 - .../rollcall/RollCallFragmentPageObject.java | 4 ++++ .../lao/event/rollcall/RollCallFragmentTest.kt | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fe2-android/app/src/main/res/layout/roll_call_fragment.xml b/fe2-android/app/src/main/res/layout/roll_call_fragment.xml index ab15d96463..b6e6afe9a1 100644 --- a/fe2-android/app/src/main/res/layout/roll_call_fragment.xml +++ b/fe2-android/app/src/main/res/layout/roll_call_fragment.xml @@ -81,7 +81,6 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/roll_call_pk_qr_code" /> - /> Date: Sat, 20 Apr 2024 20:39:10 +0200 Subject: [PATCH 07/12] Fix roll call test --- .../popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt index 8649d72fb1..a9ff193052 100644 --- a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt +++ b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt @@ -364,7 +364,6 @@ class RollCallFragmentTest { ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) ) ) - .check(ViewAssertions.matches(ViewMatchers.withText(POP_TOKEN))) } @Test From 058587e40a6389e22155d58700d79f6e1f39e117 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Sat, 20 Apr 2024 20:54:58 +0200 Subject: [PATCH 08/12] Remove duplicated code --- .../dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt index d0224241f7..dd7a6844e2 100644 --- a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt +++ b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt @@ -304,7 +304,6 @@ class RollCallFragment : AbstractEventFragment { binding.rollCallPkQrCode.visibility = View.INVISIBLE binding.rollCallPopTokenText.visibility = View.INVISIBLE } - binding.rollCallPkQrCode.visibility = if (rollCall.isOpen) View.VISIBLE else View.INVISIBLE // Don't lose time generating the QR code if it's not visible if (laoViewModel.isOrganizer || rollCall.isClosed) { From 81251a5d4d26844410ac977c2aa8315b20388c55 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Tue, 23 Apr 2024 14:28:39 +0200 Subject: [PATCH 09/12] Add android tests --- .../event/rollcall/RollCallFragmentTest.kt | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt index a9ff193052..4209cbcf1e 100644 --- a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt +++ b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt @@ -353,10 +353,36 @@ class RollCallFragmentTest { @Test @Throws(UnknownLaoException::class) - fun popTokenTest() { + fun popTokenVisibilityClientTest() { // Fake to be a client fakeClientLao() - // Check visibility as client + // Invisible while closed + RollCallFragmentPageObject.rollCallPopTokenText() + .check( + ViewAssertions.matches( + ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) + ) + ) + // Visible when opened + rollCallRepo.updateRollCall(LAO_ID, openRollCall(ROLL_CALL)) + RollCallFragmentPageObject.rollCallPopTokenText() + .check( + ViewAssertions.matches( + ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) + ) + ) + } + + @Test + @Throws(UnknownLaoException::class) + fun popTokenVisibilityOrganizerTest() { + // Always invisible + RollCallFragmentPageObject.rollCallPopTokenText() + .check( + ViewAssertions.matches( + ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) + ) + ) rollCallRepo.updateRollCall(LAO_ID, openRollCall(ROLL_CALL)) RollCallFragmentPageObject.rollCallPopTokenText() .check( From a860aada3a8b30e6a35f3fbc2983d7ed82f252b9 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Tue, 23 Apr 2024 15:36:05 +0200 Subject: [PATCH 10/12] Fix test --- .../event/rollcall/RollCallFragmentTest.kt | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt index 4209cbcf1e..088e3c41e1 100644 --- a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt +++ b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt @@ -353,14 +353,14 @@ class RollCallFragmentTest { @Test @Throws(UnknownLaoException::class) - fun popTokenVisibilityClientTest() { + fun popTokenVisibilityTest() { // Fake to be a client fakeClientLao() - // Invisible while closed + // Invisible when closed RollCallFragmentPageObject.rollCallPopTokenText() .check( ViewAssertions.matches( - ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) + ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE) ) ) // Visible when opened @@ -373,25 +373,6 @@ class RollCallFragmentTest { ) } - @Test - @Throws(UnknownLaoException::class) - fun popTokenVisibilityOrganizerTest() { - // Always invisible - RollCallFragmentPageObject.rollCallPopTokenText() - .check( - ViewAssertions.matches( - ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) - ) - ) - rollCallRepo.updateRollCall(LAO_ID, openRollCall(ROLL_CALL)) - RollCallFragmentPageObject.rollCallPopTokenText() - .check( - ViewAssertions.matches( - ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) - ) - ) - } - @Test fun reopenButtonVisibilityTest() { // Close the roll call 1 From 82b206506d53617a4750b856fd3c35f939f08cd7 Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Tue, 23 Apr 2024 16:01:17 +0200 Subject: [PATCH 11/12] Add tests --- .../event/rollcall/RollCallFragmentTest.kt | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt index 088e3c41e1..f983dcda92 100644 --- a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt +++ b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt @@ -227,6 +227,16 @@ class RollCallFragmentTest { messageSenderHelper.assertSubscriptions() } + @Test + fun managementButtonVisibilityTest() { + rollCallRepo.updateRollCall(LAO_ID, openRollCall(ROLL_CALL)) + + RollCallFragmentPageObject.managementButton() + .check( + ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) + ) + } + @Test fun scanButtonOpenScanningTest() { rollCallRepo.updateRollCall(LAO_ID, openRollCall(ROLL_CALL)) @@ -356,7 +366,7 @@ class RollCallFragmentTest { fun popTokenVisibilityTest() { // Fake to be a client fakeClientLao() - // Invisible when closed + // Invisible when created RollCallFragmentPageObject.rollCallPopTokenText() .check( ViewAssertions.matches( @@ -371,6 +381,15 @@ class RollCallFragmentTest { ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE) ) ) + + // Invisible after + rollCallRepo.updateRollCall(LAO_ID, closeRollCall(ROLL_CALL)) + RollCallFragmentPageObject.rollCallPopTokenText() + .check( + ViewAssertions.matches( + ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE) + ) + ) } @Test From b44922fa6c04eb490c648eb93f37dd5e11c216da Mon Sep 17 00:00:00 2001 From: Brice Theurillat Date: Tue, 23 Apr 2024 16:43:00 +0200 Subject: [PATCH 12/12] Update test --- .../dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt | 3 +-- .../popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt index dd7a6844e2..9abe2c818a 100644 --- a/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt +++ b/fe2-android/app/src/main/java/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragment.kt @@ -298,6 +298,7 @@ class RollCallFragment : AbstractEventFragment { // Set the QR visible only if the rollcall is opened and the user isn't the organizer if (rollCall.isOpen) { + binding.rollCallPopTokenText.text = pk binding.rollCallPkQrCode.visibility = View.VISIBLE binding.rollCallPopTokenText.visibility = View.VISIBLE } else { @@ -310,8 +311,6 @@ class RollCallFragment : AbstractEventFragment { return } - binding.rollCallPopTokenText.text = pk - val data = PopTokenData(PublicKey(pk)) val myBitmap = QRCode.from(gson.toJson(data)) diff --git a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt index f983dcda92..e1ecdd73af 100644 --- a/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt +++ b/fe2-android/app/src/test/ui/robolectric/com/github/dedis/popstellar/ui/lao/event/rollcall/RollCallFragmentTest.kt @@ -364,8 +364,6 @@ class RollCallFragmentTest { @Test @Throws(UnknownLaoException::class) fun popTokenVisibilityTest() { - // Fake to be a client - fakeClientLao() // Invisible when created RollCallFragmentPageObject.rollCallPopTokenText() .check(