• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 897326496

pending completion
897326496

Pull #3752

gitlab-ci

mzedel
chore(e2e): made use of shared timeout & login checking values to remove code duplication

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #3752: chore(e2e-tests): slightly simplified log in test + separated log out test

4395 of 6392 branches covered (68.76%)

8060 of 9780 relevant lines covered (82.41%)

126.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.41
/src/js/utils/onboardingmanager.js
1
// Copyright 2019 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React from 'react';
15

16
import CreateArtifactDialog from '../components/common/dialogs/createartifactdialog';
17
import BaseOnboardingTip from '../components/helptips/baseonboardingtip';
18
import DeploymentCompleteTip from '../components/helptips/deploymentcompletetip';
19
import OnboardingCompleteTip from '../components/helptips/onboardingcompletetip';
20
import {
21
  ApplicationUpdateReminderTip,
22
  ArtifactIncludedDeployOnboarding,
23
  ArtifactIncludedOnboarding,
24
  ArtifactModifiedOnboarding,
25
  DashboardOnboardingPendings,
26
  DashboardOnboardingState,
27
  DeploymentsInprogress,
28
  DeploymentsPast,
29
  DeploymentsPastCompletedFailure,
30
  DevicePendingTip,
31
  DevicesAcceptedOnboarding,
32
  DevicesPendingAcceptingOnboarding,
33
  GetStartedTip,
34
  SchedulingAllDevicesSelection,
35
  SchedulingArtifactSelection,
36
  SchedulingGroupSelection,
37
  SchedulingReleaseToDevices,
38
  UploadNewArtifactDialogClick,
39
  UploadNewArtifactDialogDestination,
40
  UploadNewArtifactDialogDeviceType,
41
  UploadNewArtifactDialogReleaseName,
42
  UploadNewArtifactDialogUpload,
43
  UploadNewArtifactTip,
44
  UploadPreparedArtifactTip,
45
  WelcomeSnackTip
46
} from '../components/helptips/onboardingtips';
47
import { DEPLOYMENT_STATES } from '../constants/deploymentConstants';
48
import { onboardingSteps as stepNames } from '../constants/onboardingConstants';
49

50
export const onboardingSteps = {
190✔
51
  [stepNames.ONBOARDING_START]: {
52
    condition: { min: stepNames.ONBOARDING_START, max: stepNames.DEVICES_PENDING_ONBOARDING },
53
    specialComponent: <WelcomeSnackTip progress={1} />
54
  },
55
  [stepNames.DASHBOARD_ONBOARDING_START]: {
56
    condition: { min: stepNames.ONBOARDING_START },
57
    component: GetStartedTip,
58
    progress: 1
59
  },
60
  [stepNames.DEVICES_PENDING_ONBOARDING_START]: {
61
    condition: { min: stepNames.DASHBOARD_ONBOARDING_START, max: stepNames.DEVICES_PENDING_ONBOARDING },
62
    fallbackStep: stepNames.DASHBOARD_ONBOARDING_START,
63
    specialComponent: <DevicePendingTip />
64
  },
65
  [stepNames.DEVICES_PENDING_ONBOARDING]: {
66
    condition: { min: stepNames.DASHBOARD_ONBOARDING_START },
67
    component: DashboardOnboardingState,
68
    fallbackStep: stepNames.DASHBOARD_ONBOARDING_START,
69
    progress: 1
70
  },
71
  [stepNames.DEVICES_PENDING_ACCEPTING_ONBOARDING]: {
72
    condition: { min: stepNames.DEVICES_PENDING_ONBOARDING, max: stepNames.DEVICES_ACCEPTED_ONBOARDING },
73
    component: DevicesPendingAcceptingOnboarding,
74
    progress: 1
75
  },
76
  [stepNames.DASHBOARD_ONBOARDING_PENDINGS]: {
77
    condition: { min: stepNames.DEVICES_PENDING_ONBOARDING },
78
    component: DashboardOnboardingPendings,
79
    progress: 1
80
  },
81
  [stepNames.DEVICES_ACCEPTED_ONBOARDING]: {
82
    condition: { max: stepNames.DEVICES_ACCEPTED_ONBOARDING_NOTIFICATION },
83
    component: DevicesAcceptedOnboarding,
84
    progress: 1
85
  },
86
  [stepNames.DEVICES_ACCEPTED_ONBOARDING_NOTIFICATION]: {
87
    condition: { min: stepNames.DASHBOARD_ONBOARDING_PENDINGS, max: stepNames.APPLICATION_UPDATE_REMINDER_TIP },
88
    specialComponent: <WelcomeSnackTip progress={2} />
89
  },
90
  [stepNames.APPLICATION_UPDATE_REMINDER_TIP]: {
91
    condition: { max: stepNames.ARTIFACT_INCLUDED_DEPLOY_ONBOARDING, extra: () => window.location.pathname.includes('/devices') },
×
92
    component: ApplicationUpdateReminderTip,
93
    progress: 2
94
  },
95
  [stepNames.UPLOAD_PREPARED_ARTIFACT_TIP]: {
96
    condition: { min: stepNames.DEVICES_ACCEPTED_ONBOARDING },
97
    component: UploadPreparedArtifactTip,
98
    fallbackStep: stepNames.APPLICATION_UPDATE_REMINDER_TIP,
99
    progress: 2
100
  },
101
  [stepNames.ARTIFACT_INCLUDED_ONBOARDING]: {
102
    condition: {
103
      min: stepNames.DEVICES_ACCEPTED_ONBOARDING,
104
      max: stepNames.DEPLOYMENTS_INPROGRESS,
105
      extra: () => !window.location.pathname.substring(window.location.pathname.indexOf('/releases') + '/releases'.length).length
×
106
    },
107
    component: ArtifactIncludedOnboarding,
108
    fallbackStep: stepNames.APPLICATION_UPDATE_REMINDER_TIP,
109
    progress: 1
110
  },
111
  [stepNames.ARTIFACT_INCLUDED_DEPLOY_ONBOARDING]: {
112
    condition: { max: stepNames.DEPLOYMENTS_INPROGRESS },
113
    component: ArtifactIncludedDeployOnboarding,
114
    fallbackStep: stepNames.ARTIFACT_INCLUDED_ONBOARDING,
115
    progress: 1
116
  },
117
  [stepNames.SCHEDULING_ALL_DEVICES_SELECTION]: {
118
    condition: { min: stepNames.ARTIFACT_INCLUDED_ONBOARDING, max: stepNames.DEPLOYMENTS_INPROGRESS },
119
    component: SchedulingAllDevicesSelection,
120
    fallbackStep: stepNames.ARTIFACT_INCLUDED_ONBOARDING,
121
    progress: 2
122
  },
123
  [stepNames.SCHEDULING_GROUP_SELECTION]: {
124
    condition: { min: stepNames.ARTIFACT_INCLUDED_ONBOARDING, max: stepNames.DEPLOYMENTS_INPROGRESS },
125
    component: SchedulingGroupSelection,
126
    fallbackStep: stepNames.ARTIFACT_INCLUDED_ONBOARDING,
127
    progress: 2
128
  },
129
  [stepNames.SCHEDULING_ARTIFACT_SELECTION]: {
130
    condition: { min: stepNames.SCHEDULING_ALL_DEVICES_SELECTION, max: stepNames.DEPLOYMENTS_INPROGRESS },
131
    component: SchedulingArtifactSelection,
132
    fallbackStep: stepNames.ARTIFACT_INCLUDED_ONBOARDING,
133
    progress: 2
134
  },
135
  [stepNames.SCHEDULING_RELEASE_TO_DEVICES]: {
136
    condition: { min: stepNames.SCHEDULING_ARTIFACT_SELECTION, max: stepNames.DEPLOYMENTS_INPROGRESS },
137
    component: SchedulingReleaseToDevices,
138
    fallbackStep: stepNames.ARTIFACT_INCLUDED_ONBOARDING
139
  },
140
  [stepNames.DEPLOYMENTS_INPROGRESS]: {
141
    condition: {},
142
    component: DeploymentsInprogress,
143
    progress: 2
144
  },
145
  [stepNames.DEPLOYMENTS_PAST]: {
146
    condition: { min: stepNames.DEPLOYMENTS_INPROGRESS, extra: () => !window.location.pathname.includes(DEPLOYMENT_STATES.finished) },
×
147
    component: DeploymentsPast,
148
    progress: 3
149
  },
150
  [stepNames.DEPLOYMENTS_PAST_COMPLETED_NOTIFICATION]: {
151
    condition: { min: stepNames.DEPLOYMENTS_PAST },
152
    specialComponent: <WelcomeSnackTip progress={3} />
153
  },
154
  [stepNames.DEPLOYMENTS_PAST_COMPLETED]: {
155
    condition: { min: stepNames.DEPLOYMENTS_PAST_COMPLETED_NOTIFICATION, max: stepNames.DEPLOYMENTS_PAST_COMPLETED_FAILURE },
156
    specialComponent: <DeploymentCompleteTip targetUrl="destination-unreachable" />
157
  },
158
  [stepNames.DEPLOYMENTS_PAST_COMPLETED_FAILURE]: {
159
    condition: { max: stepNames.ARTIFACT_CREATION_DIALOG },
160
    component: DeploymentsPastCompletedFailure
161
  },
162
  [stepNames.ARTIFACT_CREATION_DIALOG]: {
163
    condition: { max: stepNames.UPLOAD_NEW_ARTIFACT_TIP },
164
    specialComponent: <CreateArtifactDialog />
165
  },
166
  [stepNames.UPLOAD_NEW_ARTIFACT_TIP]: {
167
    condition: {},
168
    component: UploadNewArtifactTip,
169
    progress: 2
170
  },
171
  [stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_UPLOAD]: {
172
    condition: { min: stepNames.UPLOAD_NEW_ARTIFACT_TIP },
173
    component: UploadNewArtifactDialogUpload,
174
    fallbackStep: stepNames.UPLOAD_NEW_ARTIFACT_TIP,
175
    progress: 2
176
  },
177
  [stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_DESTINATION]: {
178
    condition: { min: stepNames.UPLOAD_NEW_ARTIFACT_TIP, max: stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_RELEASE_NAME },
179
    component: UploadNewArtifactDialogDestination,
180
    fallbackStep: stepNames.UPLOAD_NEW_ARTIFACT_TIP,
181
    progress: 2
182
  },
183
  [stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_RELEASE_NAME]: {
184
    condition: { min: stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_DESTINATION },
185
    component: UploadNewArtifactDialogReleaseName,
186
    fallbackStep: stepNames.UPLOAD_NEW_ARTIFACT_TIP,
187
    progress: 2
188
  },
189
  [stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_DEVICE_TYPE]: {
190
    condition: { min: stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_RELEASE_NAME },
191
    component: UploadNewArtifactDialogDeviceType,
192
    fallbackStep: stepNames.UPLOAD_NEW_ARTIFACT_TIP,
193
    progress: 2
194
  },
195
  [stepNames.UPLOAD_NEW_ARTIFACT_DIALOG_CLICK]: {
196
    condition: {},
197
    component: UploadNewArtifactDialogClick,
198
    fallbackStep: stepNames.UPLOAD_NEW_ARTIFACT_TIP,
199
    progress: 2
200
  },
201
  [stepNames.ARTIFACT_MODIFIED_ONBOARDING]: {
202
    condition: {},
203
    component: ArtifactModifiedOnboarding,
204
    progress: 1
205
  },
206
  [stepNames.ONBOARDING_FINISHED]: {
207
    condition: {},
208
    specialComponent: <OnboardingCompleteTip targetUrl="destination-unreachable" />
209
  },
210
  [stepNames.ONBOARDING_FINISHED_NOTIFICATION]: {
211
    condition: { min: stepNames.ONBOARDING_FINISHED },
212
    specialComponent: <WelcomeSnackTip progress={4} />
213
  },
214
  [stepNames.ONBOARDING_CANCELED]: {
215
    condition: { extra: () => true },
×
216
    specialComponent: <div />,
217
    progress: 3
218
  }
219
};
220

221
const getOnboardingStepCompleted = (id, progress, complete, showHelptips, showTips) => {
190✔
222
  const keys = Object.keys(onboardingSteps);
1,607✔
223
  const {
224
    min = id,
410✔
225
    max = id,
560✔
226
    extra
227
  } = Object.entries(onboardingSteps).reduce((accu, [key, value]) => {
1,607✔
228
    if (key === id) {
51,424✔
229
      return value.condition;
1,607✔
230
    }
231
    return accu;
49,817✔
232
  }, {});
233
  const progressIndex = keys.findIndex(step => step === progress);
40,033✔
234
  return (
1,607✔
235
    !complete &&
4,490!
236
    showHelptips &&
237
    showTips &&
238
    progressIndex >= keys.findIndex(step => step === min) &&
×
239
    progressIndex <= keys.findIndex(step => step === max) &&
×
240
    (extra ? extra() : true)
×
241
  );
242
};
243

244
export const getOnboardingComponentFor = (id, componentProps, params = {}, previousComponent = null) => {
190✔
245
  const step = onboardingSteps[id];
1,607✔
246
  const isValid = getOnboardingStepCompleted(id, componentProps.progress, componentProps.complete, componentProps.showHelptips, componentProps.showTips);
1,607✔
247
  if (!isValid) {
1,607!
248
    return previousComponent;
1,607✔
249
  }
250
  if (step.specialComponent) {
×
251
    return React.cloneElement(step.specialComponent, params);
×
252
  }
253
  const component = step.component(componentProps);
×
254
  return <BaseOnboardingTip id={id} component={component} progress={step.progress || params.progress || null} {...params} />;
×
255
};
256

257
export const applyOnboardingFallbacks = progress => {
190✔
258
  const step = onboardingSteps[progress];
2✔
259
  if (step && step.fallbackStep) {
2!
260
    return step.fallbackStep;
×
261
  }
262
  return progress;
2✔
263
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc