@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.
Files changed (125) hide show
  1. package/package.json +17 -16
  2. package/src/__e2e__/header-bar.e2e.stories.js +26 -0
  3. package/src/__e2e__/stories/common.js +226 -0
  4. package/src/__e2e__/stories/custom-application-title.js +19 -0
  5. package/src/__e2e__/stories/default.js +13 -0
  6. package/src/__e2e__/stories/me-with-avatar.js +27 -0
  7. package/src/__e2e__/stories/modulesWithSpecialCharacters.js +229 -0
  8. package/src/__e2e__/stories/online-status-message.js +49 -0
  9. package/src/__e2e__/stories/pwa-enabled.js +17 -0
  10. package/src/__e2e__/stories/user-has-all-authority.js +20 -0
  11. package/src/__e2e__/stories/user-has-no-authorities.js +20 -0
  12. package/src/__e2e__/stories/user-has-web-interpretation-and-messaging-authority.js +22 -0
  13. package/src/__e2e__/stories/user-has-web-interpretation-authority.js +22 -0
  14. package/src/__e2e__/stories/user-has-web-messaging-authority.js +22 -0
  15. package/src/__e2e__/stories/with-debug-info-edge-cases.js +51 -0
  16. package/src/__e2e__/stories/with-special-app-name-character.js +23 -0
  17. package/src/__e2e__/stories/with-update-available-notification.js +39 -0
  18. package/src/__e2e__/stories/zero-unread-interpretations.js +19 -0
  19. package/src/__e2e__/stories/zero-unread-messages.js +19 -0
  20. package/src/apps.js +276 -0
  21. package/src/debug-info/debug-info-menu-item.js +72 -0
  22. package/src/debug-info/debug-info-modal.js +47 -0
  23. package/src/debug-info/debug-info-table.js +51 -0
  24. package/src/debug-info/use-debug-info.js +15 -0
  25. package/src/features/common/index.js +14 -0
  26. package/src/features/the_headerbar_can_display_online_status/the_headerbar_displays_online_status.js +158 -0
  27. package/src/features/the_headerbar_can_display_online_status.feature +57 -0
  28. package/src/features/the_headerbar_conditionally_renders_notification_icons/the_headerbar_conditionally_renders_notification_icons.js +43 -0
  29. package/src/features/the_headerbar_conditionally_renders_notification_icons.feature +26 -0
  30. package/src/features/the_headerbar_contains_a_menu_to_all_apps/common.js +5 -0
  31. package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_app_menu_closes_when_the_user_clicks_outside.js +9 -0
  32. package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_headerbar_contains_a_menu_icon.js +5 -0
  33. package/src/features/the_headerbar_contains_a_menu_to_all_apps/the_user_will_be_offered_a_menu_with_5_apps.js +16 -0
  34. package/src/features/the_headerbar_contains_a_menu_to_all_apps.feature +21 -0
  35. package/src/features/the_headerbar_contains_a_profile_menu/common.js +14 -0
  36. 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
  37. package/src/features/the_headerbar_contains_a_profile_menu/the_headerbar_shows_an_image_icon_if_the_user_has_an_avatar.js +23 -0
  38. package/src/features/the_headerbar_contains_a_profile_menu/the_menu_is_closed_by_default.js +1 -0
  39. package/src/features/the_headerbar_contains_a_profile_menu/the_menu_opens.js +14 -0
  40. package/src/features/the_headerbar_contains_a_profile_menu/the_profile_menu_closes_when_the_user_clicks_outside.js +5 -0
  41. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_edit_his_profile.js +7 -0
  42. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_his_account.js +7 -0
  43. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_about_dhis2_page.js +7 -0
  44. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_help_page.js +7 -0
  45. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_go_to_the_settings.js +7 -0
  46. package/src/features/the_headerbar_contains_a_profile_menu/the_user_can_log_out.js +53 -0
  47. package/src/features/the_headerbar_contains_a_profile_menu/the_user_name_and_email_are_displayed.js +22 -0
  48. package/src/features/the_headerbar_contains_a_profile_menu.feature +73 -0
  49. 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
  50. package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count/there_are_no_unread_interpretations.js +9 -0
  51. package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count/there_are_some_unread_interpretations.js +12 -0
  52. package/src/features/the_headerbar_displays_a_link_to_interpretations_and_an_unread_count.feature +13 -0
  53. 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
  54. package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count/there_are_no_unread_messages.js +9 -0
  55. package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count/there_are_some_unread_messages.js +7 -0
  56. package/src/features/the_headerbar_displays_a_link_to_messages_and_an_unread_count.feature +13 -0
  57. package/src/features/the_headerbar_should_contain_a_logo_that_links_to_the_homepage/headerbar_contains_logo.js +12 -0
  58. package/src/features/the_headerbar_should_contain_a_logo_that_links_to_the_homepage.feature +6 -0
  59. package/src/features/the_headerbar_should_display_app_update_notification/index.js +52 -0
  60. package/src/features/the_headerbar_should_display_app_update_notification.feature +22 -0
  61. package/src/features/the_headerbar_should_display_debug_version_infos/index.js +130 -0
  62. package/src/features/the_headerbar_should_display_debug_version_infos.feature +52 -0
  63. 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
  64. package/src/features/the_headerbar_should_display_the_title_provided_by_the_backend_and_the_app.feature +5 -0
  65. package/src/features/the_search_should_escape_regexp_character/common.js +6 -0
  66. package/src/features/the_search_should_escape_regexp_character/the_modules_do_not_contain_items_with_special_chars.js +23 -0
  67. package/src/features/the_search_should_escape_regexp_character/the_user_searches_for_an_app_with_a_regex_character.js +29 -0
  68. package/src/features/the_search_should_escape_regexp_character.feature +48 -0
  69. package/src/header-bar-context.js +28 -0
  70. package/src/header-bar.js +145 -0
  71. package/src/header-bar.prod.stories.js +303 -0
  72. package/src/index.js +1 -0
  73. package/src/join-path.js +4 -0
  74. package/src/locales/ar/translations.json +24 -0
  75. package/src/locales/ar_IQ/translations.json +24 -0
  76. package/src/locales/bn/translations.json +12 -0
  77. package/src/locales/ckb/translations.json +23 -0
  78. package/src/locales/cs/translations.json +24 -0
  79. package/src/locales/da/translations.json +24 -0
  80. package/src/locales/en/translations.json +25 -0
  81. package/src/locales/en_US/translations.json +25 -0
  82. package/src/locales/es/translations.json +25 -0
  83. package/src/locales/es_419/translations.json +24 -0
  84. package/src/locales/fr/translations.json +25 -0
  85. package/src/locales/hi_IN/translations.json +25 -0
  86. package/src/locales/id/translations.json +24 -0
  87. package/src/locales/index.js +88 -0
  88. package/src/locales/km/translations.json +24 -0
  89. package/src/locales/lo/translations.json +24 -0
  90. package/src/locales/my/translations.json +24 -0
  91. package/src/locales/nb/translations.json +24 -0
  92. package/src/locales/nl/translations.json +24 -0
  93. package/src/locales/or/translations.json +12 -0
  94. package/src/locales/prs/translations.json +24 -0
  95. package/src/locales/ps/translations.json +24 -0
  96. package/src/locales/pt/translations.json +25 -0
  97. package/src/locales/pt_BR/translations.json +24 -0
  98. package/src/locales/ro/translations.json +23 -0
  99. package/src/locales/ru/translations.json +24 -0
  100. package/src/locales/si/translations.json +24 -0
  101. package/src/locales/sv/translations.json +24 -0
  102. package/src/locales/tet/translations.json +24 -0
  103. package/src/locales/tg/translations.json +24 -0
  104. package/src/locales/uk/translations.json +24 -0
  105. package/src/locales/ur/translations.json +24 -0
  106. package/src/locales/uz_Latn/translations.json +23 -0
  107. package/src/locales/uz_UZ_Cyrl/translations.json +24 -0
  108. package/src/locales/uz_UZ_Latn/translations.json +24 -0
  109. package/src/locales/vi/translations.json +24 -0
  110. package/src/locales/zh/translations.json +25 -0
  111. package/src/locales/zh_CN/translations.json +24 -0
  112. package/src/logo-image.js +71 -0
  113. package/src/logo.js +45 -0
  114. package/src/notification-icon.js +91 -0
  115. package/src/notifications.js +63 -0
  116. package/src/online-status.js +40 -0
  117. package/src/online-status.styles.js +91 -0
  118. package/src/profile/use-on-doc-click.js +23 -0
  119. package/src/profile/use-on-doc-click.test.js +40 -0
  120. package/src/profile-menu/index.js +1 -0
  121. package/src/profile-menu/profile-header.js +118 -0
  122. package/src/profile-menu/profile-menu.js +176 -0
  123. package/src/profile-menu/update-notification.js +67 -0
  124. package/src/profile.js +101 -0
  125. 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,5 @@
1
+ import { Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Then('the HeaderBar contains a link to the interpretations', () => {
4
+ cy.get('[data-test="headerbar-interpretations"]').should('be.visible')
5
+ })
@@ -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
+ )
@@ -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,5 @@
1
+ import { Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Then('the HeaderBar contains a link to the messages', () => {
4
+ cy.get('[data-test="headerbar-messages"]').should('be.visible')
5
+ })
@@ -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,6 @@
1
+ Feature: The HeaderBar should contain a logo that links to the homepage
2
+
3
+ Scenario: HeaderBar contains logo
4
+ Given the HeaderBar loads without an error
5
+ Then the HeaderBar should display the dhis2 logo
6
+ And the logo should link to the homepage
@@ -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,5 @@
1
+ Feature: The HeaderBar should display the title provided by the backend and the app
2
+
3
+ Scenario: The HeaderBar displays the custom title
4
+ Given the custom title is "Barbaz" and the app title is "Example!"
5
+ Then the displayed title should be "Barbaz - Example!"
@@ -0,0 +1,6 @@
1
+ import { Given } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given(/the search contains a (.*)/, (character) => {
4
+ cy.get('[data-test="headerbar-apps-icon"]').click()
5
+ cy.get('#filter').type(character)
6
+ })
@@ -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)