@dhis2-ui/header-bar 10.16.2 → 10.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -16
- package/src/__e2e__/header-bar.e2e.stories.js +26 -0
- package/src/__e2e__/stories/common.js +226 -0
- package/src/__e2e__/stories/custom-application-title.js +19 -0
- package/src/__e2e__/stories/default.js +13 -0
- package/src/__e2e__/stories/me-with-avatar.js +27 -0
- package/src/__e2e__/stories/modulesWithSpecialCharacters.js +229 -0
- package/src/__e2e__/stories/online-status-message.js +49 -0
- package/src/__e2e__/stories/pwa-enabled.js +17 -0
- package/src/__e2e__/stories/user-has-all-authority.js +20 -0
- package/src/__e2e__/stories/user-has-no-authorities.js +20 -0
- package/src/__e2e__/stories/user-has-web-interpretation-and-messaging-authority.js +22 -0
- package/src/__e2e__/stories/user-has-web-interpretation-authority.js +22 -0
- package/src/__e2e__/stories/user-has-web-messaging-authority.js +22 -0
- package/src/__e2e__/stories/with-debug-info-edge-cases.js +51 -0
- package/src/__e2e__/stories/with-special-app-name-character.js +23 -0
- package/src/__e2e__/stories/with-update-available-notification.js +39 -0
- package/src/__e2e__/stories/zero-unread-interpretations.js +19 -0
- package/src/__e2e__/stories/zero-unread-messages.js +19 -0
- package/src/apps.js +276 -0
- package/src/debug-info/debug-info-menu-item.js +72 -0
- package/src/debug-info/debug-info-modal.js +47 -0
- package/src/debug-info/debug-info-table.js +51 -0
- package/src/debug-info/use-debug-info.js +15 -0
- package/src/features/common/index.js +14 -0
- package/src/features/the_headerbar_can_display_online_status/the_headerbar_displays_online_status.js +158 -0
- package/src/features/the_headerbar_can_display_online_status.feature +57 -0
- package/src/features/the_headerbar_conditionally_renders_notification_icons/the_headerbar_conditionally_renders_notification_icons.js +43 -0
- package/src/features/the_headerbar_conditionally_renders_notification_icons.feature +26 -0
- package/src/features/the_headerbar_contains_a_menu_to_all_apps/common.js +5 -0
- package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_app_menu_closes_when_the_user_clicks_outside.js +9 -0
- package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_headerbar_contains_a_menu_icon.js +5 -0
- package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_user_will_be_offered_a_menu_with_5_apps.js +16 -0
- package/src/features/the_headerbar_contains_a_menu_to_all_apps.feature +21 -0
- package/src/features/the_headerbar_contains_a_profile_menu/common.js +14 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_headerbar_shows_a_text_icon_if_the_user_does_not_have_an_avatar.js +30 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_headerbar_shows_an_image_icon_if_the_user_has_an_avatar.js +23 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_menu_is_closed_by_default.js +1 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_menu_opens.js +14 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_profile_menu_closes_when_the_user_clicks_outside.js +5 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_edit_his_profile.js +7 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_his_account.js +7 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_about_dhis2_page.js +7 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_help_page.js +7 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_settings.js +7 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_log_out.js +53 -0
- package/src/features/the_headerbar_contains_a_profile_menu/the_user_name_and_email_are_displayed.js +22 -0
- package/src/features/the_headerbar_contains_a_profile_menu.feature +73 -0
- package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count/the_headerbar_displays_a_link_to_the_interpretations.js +5 -0
- package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count/there_are_no_unread_interpretations.js +9 -0
- package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count/there_are_some_unread_interpretations.js +12 -0
- package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count.feature +13 -0
- package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count/the_headerbar_displays_a_link_to_the_messages.js +5 -0
- package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count/there_are_no_unread_messages.js +9 -0
- package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count/there_are_some_unread_messages.js +7 -0
- package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count.feature +13 -0
- package/src/features/the_headerbar_should_contain_a_logo_that_links_to_the_homepage/headerbar_contains_logo.js +12 -0
- package/src/features/the_headerbar_should_contain_a_logo_that_links_to_the_homepage.feature +6 -0
- package/src/features/the_headerbar_should_display_app_update_notification/index.js +52 -0
- package/src/features/the_headerbar_should_display_app_update_notification.feature +22 -0
- package/src/features/the_headerbar_should_display_debug_version_infos/index.js +130 -0
- package/src/features/the_headerbar_should_display_debug_version_infos.feature +52 -0
- package/src/features/the_headerbar_should_display_the_title_provided_by_the_backend_and_the_app/the_headerbar_displays_the_custom_title.js +11 -0
- package/src/features/the_headerbar_should_display_the_title_provided_by_the_backend_and_the_app.feature +5 -0
- package/src/features/the_search_should_escape_regexp_character/common.js +6 -0
- package/src/features/the_search_should_escape_regexp_character/the_modules_do_not_contain_items_with_special_chars.js +23 -0
- package/src/features/the_search_should_escape_regexp_character/the_user_searches_for_an_app_with_a_regex_character.js +29 -0
- package/src/features/the_search_should_escape_regexp_character.feature +48 -0
- package/src/header-bar-context.js +28 -0
- package/src/header-bar.js +145 -0
- package/src/header-bar.prod.stories.js +303 -0
- package/src/index.js +1 -0
- package/src/join-path.js +4 -0
- package/src/locales/ar/translations.json +24 -0
- package/src/locales/ar_IQ/translations.json +24 -0
- package/src/locales/bn/translations.json +12 -0
- package/src/locales/ckb/translations.json +23 -0
- package/src/locales/cs/translations.json +24 -0
- package/src/locales/da/translations.json +24 -0
- package/src/locales/en/translations.json +25 -0
- package/src/locales/en_US/translations.json +25 -0
- package/src/locales/es/translations.json +25 -0
- package/src/locales/es_419/translations.json +24 -0
- package/src/locales/fr/translations.json +25 -0
- package/src/locales/hi_IN/translations.json +25 -0
- package/src/locales/id/translations.json +24 -0
- package/src/locales/index.js +88 -0
- package/src/locales/km/translations.json +24 -0
- package/src/locales/lo/translations.json +24 -0
- package/src/locales/my/translations.json +24 -0
- package/src/locales/nb/translations.json +24 -0
- package/src/locales/nl/translations.json +24 -0
- package/src/locales/or/translations.json +12 -0
- package/src/locales/prs/translations.json +24 -0
- package/src/locales/ps/translations.json +24 -0
- package/src/locales/pt/translations.json +25 -0
- package/src/locales/pt_BR/translations.json +24 -0
- package/src/locales/ro/translations.json +23 -0
- package/src/locales/ru/translations.json +24 -0
- package/src/locales/si/translations.json +24 -0
- package/src/locales/sv/translations.json +24 -0
- package/src/locales/tet/translations.json +24 -0
- package/src/locales/tg/translations.json +24 -0
- package/src/locales/uk/translations.json +24 -0
- package/src/locales/ur/translations.json +24 -0
- package/src/locales/uz_Latn/translations.json +23 -0
- package/src/locales/uz_UZ_Cyrl/translations.json +24 -0
- package/src/locales/uz_UZ_Latn/translations.json +24 -0
- package/src/locales/vi/translations.json +24 -0
- package/src/locales/zh/translations.json +25 -0
- package/src/locales/zh_CN/translations.json +24 -0
- package/src/logo-image.js +71 -0
- package/src/logo.js +45 -0
- package/src/notification-icon.js +91 -0
- package/src/notifications.js +63 -0
- package/src/online-status.js +40 -0
- package/src/online-status.styles.js +91 -0
- package/src/profile/use-on-doc-click.js +23 -0
- package/src/profile/use-on-doc-click.test.js +40 -0
- package/src/profile-menu/index.js +1 -0
- package/src/profile-menu/profile-header.js +118 -0
- package/src/profile-menu/profile-menu.js +176 -0
- package/src/profile-menu/update-notification.js +67 -0
- package/src/profile.js +101 -0
- package/src/title.js +23 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Feature: The HeaderBar contains a profile menu
|
|
2
|
+
|
|
3
|
+
Scenario: The HeaderBar shows a text icon if the user does not have an avatar
|
|
4
|
+
Given the HeaderBar loads without an error and the user does not have an avatar
|
|
5
|
+
Then the headerbar contains a text icon of size 36px
|
|
6
|
+
When the user clicks on the text icon
|
|
7
|
+
Then the profile menu contains a text icon of size 48px
|
|
8
|
+
|
|
9
|
+
Scenario: The HeaderBar shows an image icon if the user has an avatar
|
|
10
|
+
Given the HeaderBar loads without an error and the user has an avatar
|
|
11
|
+
Then the headerbar contains an image icon of size 36px
|
|
12
|
+
When the user clicks on the image icon
|
|
13
|
+
Then the profile menu contains an image icon of size 48px
|
|
14
|
+
|
|
15
|
+
Scenario: The menu is closed by default
|
|
16
|
+
Given the HeaderBar loads without an error
|
|
17
|
+
Then the HeaderBar does not display the profile menu
|
|
18
|
+
|
|
19
|
+
Scenario: The menu opens
|
|
20
|
+
Given the HeaderBar loads without an error
|
|
21
|
+
When the user clicks on the profile icons
|
|
22
|
+
Then the menu opens
|
|
23
|
+
|
|
24
|
+
Scenario: The user name and email are displayed
|
|
25
|
+
Given the HeaderBar loads without an error
|
|
26
|
+
When the user opens the menu
|
|
27
|
+
And contains the user name
|
|
28
|
+
And contains the user email
|
|
29
|
+
|
|
30
|
+
Scenario: The user can edit his profile
|
|
31
|
+
Given the HeaderBar loads without an error
|
|
32
|
+
When the user opens the menu
|
|
33
|
+
Then contains a link to edit the profile
|
|
34
|
+
|
|
35
|
+
Scenario: The user can go to the settings
|
|
36
|
+
Given the HeaderBar loads without an error
|
|
37
|
+
When the user opens the menu
|
|
38
|
+
Then contains a link to the settings
|
|
39
|
+
|
|
40
|
+
Scenario: The user can go to his account
|
|
41
|
+
Given the HeaderBar loads without an error
|
|
42
|
+
When the user opens the menu
|
|
43
|
+
Then contains a link to the user account
|
|
44
|
+
|
|
45
|
+
Scenario: The user can go to the help page
|
|
46
|
+
Given the HeaderBar loads without an error
|
|
47
|
+
When the user opens the menu
|
|
48
|
+
Then contains a link to the help page
|
|
49
|
+
|
|
50
|
+
Scenario: The user can go to the About DHIS2 page
|
|
51
|
+
Given the HeaderBar loads without an error
|
|
52
|
+
When the user opens the menu
|
|
53
|
+
Then contains a link to the About DHIS2 page
|
|
54
|
+
|
|
55
|
+
Scenario: The user can log out
|
|
56
|
+
Given the HeaderBar loads without an error
|
|
57
|
+
When the user opens the menu
|
|
58
|
+
Then contains a link to log out the user
|
|
59
|
+
And there is no loading mask
|
|
60
|
+
|
|
61
|
+
# The following are omitted because of testing complications
|
|
62
|
+
# around navigation:
|
|
63
|
+
|
|
64
|
+
# Then the user clicks the link to log out
|
|
65
|
+
# Then a loading mask covers the screen
|
|
66
|
+
# And clearSensitiveCaches is called
|
|
67
|
+
# Then the window navigates to the logout URL
|
|
68
|
+
|
|
69
|
+
Scenario: The profile menu closes when the user clicks outside
|
|
70
|
+
Given the HeaderBar loads without an error
|
|
71
|
+
When the user opens the menu
|
|
72
|
+
And the user clicks outside of the menu
|
|
73
|
+
Then the HeaderBar does not display the profile menu
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('there are 0 unread interpretations', () => {
|
|
4
|
+
cy.visitStory('HeaderBarTesting', 'Zero Unread Interpretations')
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
Then('the interpretations link does not contain a count', () => {
|
|
8
|
+
cy.get('[data-test="headerbar-interpretations-count"]').should('not.exist')
|
|
9
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Then(
|
|
4
|
+
'the interpretations link contains an icon with a number greater than 0',
|
|
5
|
+
() => {
|
|
6
|
+
cy.get('[data-test="headerbar-interpretations-count"]').should(
|
|
7
|
+
($count) => {
|
|
8
|
+
expect(parseInt($count.text(), 10)).to.be.greaterThan(0)
|
|
9
|
+
}
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
)
|
package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count.feature
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Feature: The HeaderBar displays a link to interpretations and an unread count
|
|
2
|
+
|
|
3
|
+
Scenario: The HeaderBar displays a link to the interpretations
|
|
4
|
+
Given the HeaderBar loads without an error
|
|
5
|
+
Then the HeaderBar contains a link to the interpretations
|
|
6
|
+
|
|
7
|
+
Scenario: There are some unread interpretations
|
|
8
|
+
Given the HeaderBar loads without an error
|
|
9
|
+
Then the interpretations link contains an icon with a number greater than 0
|
|
10
|
+
|
|
11
|
+
Scenario: There are no unread interpretations
|
|
12
|
+
Given there are 0 unread interpretations
|
|
13
|
+
Then the interpretations link does not contain a count
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Then, Given } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('there are 0 unread messages', () => {
|
|
4
|
+
cy.visitStory('HeaderBarTesting', 'Zero Unread Messages')
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
Then('the messages link does not contain a count', () => {
|
|
8
|
+
cy.get('[data-test="headerbar-messages-count"]').should('not.exist')
|
|
9
|
+
})
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Then('the messages link contains an icon with a number greater than 0', () => {
|
|
4
|
+
cy.get('[data-test="headerbar-messages-count"]').should(($count) => {
|
|
5
|
+
expect(parseInt($count.text(), 10)).to.be.greaterThan(0)
|
|
6
|
+
})
|
|
7
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Feature: The HeaderBar displays a link to messages and an unread count
|
|
2
|
+
|
|
3
|
+
Scenario: The HeaderBar displays a link to the messages
|
|
4
|
+
Given the HeaderBar loads without an error
|
|
5
|
+
Then the HeaderBar contains a link to the messages
|
|
6
|
+
|
|
7
|
+
Scenario: There are some unread messages
|
|
8
|
+
Given the HeaderBar loads without an error
|
|
9
|
+
Then the messages link contains an icon with a number greater than 0
|
|
10
|
+
|
|
11
|
+
Scenario: There are no unread messages
|
|
12
|
+
Given there are 0 unread messages
|
|
13
|
+
Then the messages link does not contain a count
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
import { baseUrl } from '../common/index.js'
|
|
3
|
+
|
|
4
|
+
Then('the HeaderBar should display the dhis2 logo', () => {
|
|
5
|
+
cy.get('[data-test="headerbar-logo"]').should('be.visible')
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
Then('the logo should link to the homepage', () => {
|
|
9
|
+
cy.get('[data-test="headerbar-logo"] a').should(($a) => {
|
|
10
|
+
expect($a.attr('href')).to.equal(baseUrl)
|
|
11
|
+
})
|
|
12
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('the HeaderBar is rendered without an available update', () => {
|
|
4
|
+
cy.visitStory('HeaderBarTesting', 'default')
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
Given('the HeaderBar is rendered with an available update', () => {
|
|
8
|
+
cy.visitStory('HeaderBarTesting', 'With Update Available Notification')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
Given(
|
|
12
|
+
'the HeaderBar is rendered with no app name and an available update',
|
|
13
|
+
() => {
|
|
14
|
+
cy.visitStory(
|
|
15
|
+
'HeaderBarTesting',
|
|
16
|
+
'With Update Available Notification No App Name'
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
When('the user opens the profile menu', () => {
|
|
22
|
+
cy.get('[data-test="headerbar-profile"] > button').click()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
Then('the update notification should not be displayed', () => {
|
|
26
|
+
cy.get('[data-test="dhis2-ui-headerbar-updatenotification"]').should(
|
|
27
|
+
'not.exist'
|
|
28
|
+
)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
Then('the update notification should be displayed', () => {
|
|
32
|
+
cy.get('[data-test="dhis2-ui-headerbar-updatenotification"]')
|
|
33
|
+
.should('contain', 'New Data Visualizer version available')
|
|
34
|
+
.should('contain', 'Click to reload')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
Then('the update notification should be displayed without app name', () => {
|
|
38
|
+
cy.get('[data-test="dhis2-ui-headerbar-updatenotification"]')
|
|
39
|
+
.should('contain', 'New app version available')
|
|
40
|
+
.should('contain', 'Click to reload')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
When('the user clicks the update notification', () => {
|
|
44
|
+
cy.get('[data-test="dhis2-ui-headerbar-updatenotification"]').click()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
Then('the profile menu should not be shown', () => {
|
|
48
|
+
cy.get('[data-test="headerbar-profile-menu"]').should('not.exist')
|
|
49
|
+
})
|
|
50
|
+
Then('a callback should display a test div', () => {
|
|
51
|
+
cy.contains('The callback was successful').should('be.visible')
|
|
52
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Feature: The HeaderBar should display app update notification
|
|
2
|
+
|
|
3
|
+
Scenario: No app update is available
|
|
4
|
+
Given the HeaderBar is rendered without an available update
|
|
5
|
+
When the user opens the profile menu
|
|
6
|
+
Then the update notification should not be displayed
|
|
7
|
+
|
|
8
|
+
Scenario: An app update is available
|
|
9
|
+
Given the HeaderBar is rendered with an available update
|
|
10
|
+
When the user opens the profile menu
|
|
11
|
+
Then the update notification should be displayed
|
|
12
|
+
|
|
13
|
+
Scenario: A callback is executed when the user click on the update notification
|
|
14
|
+
Given the HeaderBar is rendered with an available update
|
|
15
|
+
When the user opens the profile menu
|
|
16
|
+
When the user clicks the update notification
|
|
17
|
+
Then a callback should display a test div
|
|
18
|
+
|
|
19
|
+
Scenario: An app update is available but not app name was specified
|
|
20
|
+
Given the HeaderBar is rendered with no app name and an available update
|
|
21
|
+
When the user opens the profile menu
|
|
22
|
+
Then the update notification should be displayed without app name
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given(
|
|
4
|
+
'the HeaderBar is rendered without an instance version in runtime context',
|
|
5
|
+
() => {
|
|
6
|
+
cy.visitStory('HeaderBarTesting', 'With Unknown Instance Version')
|
|
7
|
+
}
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
Given(
|
|
11
|
+
'the HeaderBar is rendered with an app name and app version in runtime context',
|
|
12
|
+
() => {
|
|
13
|
+
cy.visitStory('HeaderBarTesting', 'default')
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
Given('the HeaderBar is rendered without app name in runtime context', () => {
|
|
18
|
+
cy.visitStory('HeaderBarTesting', 'With Unknown App Name')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
Given(
|
|
22
|
+
'the HeaderBar is rendered with an app name but without app version in runtime context',
|
|
23
|
+
() => {
|
|
24
|
+
cy.visitStory('HeaderBarTesting', 'With Unknown App Version')
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
Given(
|
|
29
|
+
'the HeaderBar is rendered without app name or app version in runtime context',
|
|
30
|
+
() => {
|
|
31
|
+
cy.visitStory('HeaderBarTesting', 'With Unknown App Name And Version')
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
When('the user opens the profile menu', () => {
|
|
36
|
+
cy.get('[data-test="headerbar-profile"] > button').click()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
Then("the app's name and version should be displayed", () => {
|
|
40
|
+
cy.get('[data-test="dhis2-ui-headerbar-appinfo"]').should(
|
|
41
|
+
'contain',
|
|
42
|
+
'TestApp 101.2.3-beta.4'
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
Then("the app's name with unknown version should be displayed", () => {
|
|
47
|
+
cy.get('[data-test="dhis2-ui-headerbar-appinfo"]').should(
|
|
48
|
+
'contain',
|
|
49
|
+
'TestApp version unknown'
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
Then("the unknown app with app's version should be displayed", () => {
|
|
54
|
+
cy.get('[data-test="dhis2-ui-headerbar-appinfo"]').should(
|
|
55
|
+
'contain',
|
|
56
|
+
'App 101.2.3-beta.4'
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
Then('the unknown app with unknown version should be displayed', () => {
|
|
61
|
+
cy.get('[data-test="dhis2-ui-headerbar-appinfo"]').should(
|
|
62
|
+
'contain',
|
|
63
|
+
'App version unknown'
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
Then('the instance version should be displayed', () => {
|
|
68
|
+
cy.get('[data-test="dhis2-ui-headerbar-instanceinfo"]').should(
|
|
69
|
+
'contain',
|
|
70
|
+
'DHIS2 2.39.2.1-SNAPSHOT'
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
Then('the instance version should show as unknown', () => {
|
|
75
|
+
cy.get('[data-test="dhis2-ui-headerbar-instanceinfo"]').should(
|
|
76
|
+
'contain',
|
|
77
|
+
'DHIS2 version unknown'
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
When('the user clicks the debug info menu item', () => {
|
|
82
|
+
cy.get('[data-test="dhis2-ui-headerbar-debuginfo"] > a').click()
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
Then('the debug info modal should be shown', () => {
|
|
86
|
+
cy.get('[data-test="dhis2-ui-headerbar-debuginfomodal"]').should(
|
|
87
|
+
'be.visible'
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
Then('the debug info modal should not be shown', () => {
|
|
91
|
+
cy.get('[data-test="dhis2-ui-headerbar-debuginfomodal"]').should(
|
|
92
|
+
'not.exist'
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
Then('the debug info modal should contain debug info', () => {
|
|
97
|
+
cy.get('[data-test="dhis2-ui-headerbar-debuginfotable"]')
|
|
98
|
+
.should(
|
|
99
|
+
'contain',
|
|
100
|
+
'2.39.2.1-SNAPSHOT' // DHIS2 version
|
|
101
|
+
)
|
|
102
|
+
.should(
|
|
103
|
+
'contain',
|
|
104
|
+
'6607c3c' // Revision
|
|
105
|
+
)
|
|
106
|
+
.should(
|
|
107
|
+
'contain',
|
|
108
|
+
'TestApp' // App name
|
|
109
|
+
)
|
|
110
|
+
.should(
|
|
111
|
+
'contain',
|
|
112
|
+
'101.2.3-beta.4' // App version
|
|
113
|
+
)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
When('the user clicks the copy debug info button', () => {
|
|
117
|
+
cy.contains('Copy debug info').click()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
Then('the debug info should be copied to clipboard', () => {
|
|
121
|
+
cy.window().then((win) => {
|
|
122
|
+
win.navigator.clipboard.readText().then((text) => {
|
|
123
|
+
expect(text).to.contain('2.39.2.1-SNAPSHOT')
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
Then('the debug info copied to clipboard alert should be shown', () => {
|
|
129
|
+
cy.contains('Debug information copied to clipboard').should('exist')
|
|
130
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Feature: The HeaderBar should display debug version infos
|
|
2
|
+
|
|
3
|
+
Scenario: The debug version infos are displayed in the profile menu
|
|
4
|
+
Given the HeaderBar is rendered with an app name and app version in runtime context
|
|
5
|
+
When the user opens the profile menu
|
|
6
|
+
Then the instance version should be displayed
|
|
7
|
+
And the app's name and version should be displayed
|
|
8
|
+
|
|
9
|
+
Scenario: The debug version info modal is displayed when clicking on the menu item
|
|
10
|
+
Given the HeaderBar is rendered with an app name and app version in runtime context
|
|
11
|
+
When the user opens the profile menu
|
|
12
|
+
When the user clicks the debug info menu item
|
|
13
|
+
Then the debug info modal should be shown
|
|
14
|
+
|
|
15
|
+
Scenario: The debug version info modal displays debug info
|
|
16
|
+
Given the HeaderBar is rendered with an app name and app version in runtime context
|
|
17
|
+
When the user opens the profile menu
|
|
18
|
+
When the user clicks the debug info menu item
|
|
19
|
+
Then the debug info modal should contain debug info
|
|
20
|
+
|
|
21
|
+
Scenario: The debug version info should be copied to clipboard
|
|
22
|
+
Given the HeaderBar is rendered with an app name and app version in runtime context
|
|
23
|
+
When the user opens the profile menu
|
|
24
|
+
When the user clicks the debug info menu item
|
|
25
|
+
When the user clicks the copy debug info button
|
|
26
|
+
Then the debug info should be copied to clipboard
|
|
27
|
+
And the debug info copied to clipboard alert should be shown
|
|
28
|
+
And the debug info modal should not be shown
|
|
29
|
+
|
|
30
|
+
Scenario: The debug version infos are displayed with unknown dhis2 version in the profile menu
|
|
31
|
+
Given the HeaderBar is rendered without an instance version in runtime context
|
|
32
|
+
When the user opens the profile menu
|
|
33
|
+
Then the instance version should show as unknown
|
|
34
|
+
And the app's name and version should be displayed
|
|
35
|
+
|
|
36
|
+
Scenario: The debug version infos are displayed with unknown app name and version in the profile menu
|
|
37
|
+
Given the HeaderBar is rendered without app name or app version in runtime context
|
|
38
|
+
When the user opens the profile menu
|
|
39
|
+
Then the instance version should be displayed
|
|
40
|
+
And the unknown app with unknown version should be displayed
|
|
41
|
+
|
|
42
|
+
Scenario: The debug version infos are displayed with unknown app name in the profile menu
|
|
43
|
+
Given the HeaderBar is rendered without app name in runtime context
|
|
44
|
+
When the user opens the profile menu
|
|
45
|
+
Then the instance version should be displayed
|
|
46
|
+
And the unknown app with app's version should be displayed
|
|
47
|
+
|
|
48
|
+
Scenario: The debug version infos are displayed with unknown app version in the profile menu
|
|
49
|
+
Given the HeaderBar is rendered with an app name but without app version in runtime context
|
|
50
|
+
When the user opens the profile menu
|
|
51
|
+
Then the instance version should be displayed
|
|
52
|
+
And the app's name with unknown version should be displayed
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Then, Given } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given('the custom title is "Barbaz" and the app title is "Example!"', () => {
|
|
4
|
+
cy.visitStory('HeaderBarTesting', 'Custom Application Title')
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
Then('the displayed title should be "Barbaz - Example!"', () => {
|
|
8
|
+
cy.get('[data-test="headerbar-title"]').should(($title) => {
|
|
9
|
+
expect($title.text()).to.equal('Barbaz - Example!')
|
|
10
|
+
})
|
|
11
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
|
|
3
|
+
Given(/no app name contains a (.*)/, (character) => {
|
|
4
|
+
// Needs to be wrapped, otherwise for some reason the wrong char is in the scope
|
|
5
|
+
cy.all(
|
|
6
|
+
() => cy.window(),
|
|
7
|
+
() => cy.wrap(character)
|
|
8
|
+
).then(([win, char]) => {
|
|
9
|
+
const { dataProviderData } = win
|
|
10
|
+
const { modules } = dataProviderData['action::menu/getModules']
|
|
11
|
+
const modulesWithSpecialChar = modules.filter(
|
|
12
|
+
(module) => module.displayName.indexOf(char) !== -1
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
expect(modulesWithSpecialChar).to.have.length(0)
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
Then('no results should be shown', () => {
|
|
20
|
+
cy.get('[data-test="headerbar-apps-menu-list"] > a > div').should(
|
|
21
|
+
'not.exist'
|
|
22
|
+
)
|
|
23
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
|
|
2
|
+
import { modulesWithSpecialCharacters } from '../../__e2e__/stories/modulesWithSpecialCharacters.js'
|
|
3
|
+
|
|
4
|
+
Given(/some app names contain a (.*)/, (character) => {
|
|
5
|
+
// Needs to be wrapped, otherwise for some reason the wrong char is in the scope
|
|
6
|
+
cy.wrap(character).then((char) => {
|
|
7
|
+
cy.visitStory('HeaderBarTesting', 'With Special App Name Characters')
|
|
8
|
+
|
|
9
|
+
// verify that there's a module with the special char in its name
|
|
10
|
+
const modulesWithSpecialChar = modulesWithSpecialCharacters.filter(
|
|
11
|
+
(module) => {
|
|
12
|
+
return module.displayName.indexOf(char) !== -1
|
|
13
|
+
}
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
expect(modulesWithSpecialChar).to.have.length.of.at.least(1)
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
Then(/only apps with (.*) in their name should be shown/, (character) => {
|
|
21
|
+
cy.get('[data-test="headerbar-apps-menu-list"] > a > div').should(
|
|
22
|
+
($modules) => {
|
|
23
|
+
$modules.each((index, module) => {
|
|
24
|
+
const displayName = Cypress.$(module).text()
|
|
25
|
+
expect(displayName.indexOf(character)).to.not.eql(-1)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Feature: The search should escape regexp characters
|
|
2
|
+
|
|
3
|
+
Scenario Outline: The user searches for an app with a regex character
|
|
4
|
+
Given some app names contain a <char>
|
|
5
|
+
And the search contains a <char>
|
|
6
|
+
Then only apps with <char> in their name should be shown
|
|
7
|
+
|
|
8
|
+
Examples:
|
|
9
|
+
| char |
|
|
10
|
+
| / |
|
|
11
|
+
| ( |
|
|
12
|
+
| ) |
|
|
13
|
+
| [ |
|
|
14
|
+
| ] |
|
|
15
|
+
| { |
|
|
16
|
+
| } |
|
|
17
|
+
| * |
|
|
18
|
+
| + |
|
|
19
|
+
| ? |
|
|
20
|
+
| . |
|
|
21
|
+
| ^ |
|
|
22
|
+
| $ |
|
|
23
|
+
| \| |
|
|
24
|
+
| \\ |
|
|
25
|
+
|
|
26
|
+
Scenario Outline: The modules do not contain items with special chars
|
|
27
|
+
Given the HeaderBar loads without an error
|
|
28
|
+
And the search contains a <char>
|
|
29
|
+
And no app name contains a <char>
|
|
30
|
+
Then no results should be shown
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
| char |
|
|
34
|
+
| / |
|
|
35
|
+
| ( |
|
|
36
|
+
| ) |
|
|
37
|
+
| [ |
|
|
38
|
+
| ] |
|
|
39
|
+
| { |
|
|
40
|
+
| } |
|
|
41
|
+
| * |
|
|
42
|
+
| + |
|
|
43
|
+
| ? |
|
|
44
|
+
| . |
|
|
45
|
+
| ^ |
|
|
46
|
+
| $ |
|
|
47
|
+
| \| |
|
|
48
|
+
| \\ |
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
import React, { createContext, useContext } from 'react'
|
|
3
|
+
|
|
4
|
+
const headerBarContext = createContext({
|
|
5
|
+
updateAvailable: false,
|
|
6
|
+
onApplyAvailableUpdate: () => {},
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
export const HeaderBarContextProvider = ({
|
|
10
|
+
updateAvailable,
|
|
11
|
+
onApplyAvailableUpdate,
|
|
12
|
+
children,
|
|
13
|
+
}) => {
|
|
14
|
+
return (
|
|
15
|
+
<headerBarContext.Provider
|
|
16
|
+
value={{ updateAvailable, onApplyAvailableUpdate }}
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</headerBarContext.Provider>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
HeaderBarContextProvider.propTypes = {
|
|
23
|
+
children: PropTypes.node,
|
|
24
|
+
updateAvailable: PropTypes.bool,
|
|
25
|
+
onApplyAvailableUpdate: PropTypes.func,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const useHeaderBarContext = () => useContext(headerBarContext)
|