@dxos/shell 0.6.13 → 0.6.14-main.2b6a0f3
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/dist/bundle/shell.mjs +12070 -15401
- package/dist/bundle/shell.mjs.map +1 -1
- package/dist/bundle/shell.umd.js +87 -94
- package/dist/bundle/shell.umd.js.map +1 -1
- package/dist/bundle/style.css +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react.mjs +551 -453
- package/dist/lib/browser/react.mjs.map +4 -4
- package/dist/lib/browser/testing/index.mjs +2 -7
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/types/src/components/CompoundButton/CompoundButton.stories.js +1 -1
- package/dist/types/src/components/CompoundButton/CompoundButton.stories.js.map +1 -1
- package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts +0 -3
- package/dist/types/src/components/IdentityList/SpaceMemberList.stories.d.ts.map +1 -1
- package/dist/types/src/components/IdentityList/SpaceMemberList.stories.js +1 -2
- package/dist/types/src/components/IdentityList/SpaceMemberList.stories.js.map +1 -1
- package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts +0 -3
- package/dist/types/src/components/InvitationList/InvitationList.stories.d.ts.map +1 -1
- package/dist/types/src/components/InvitationList/InvitationList.stories.js +1 -2
- package/dist/types/src/components/InvitationList/InvitationList.stories.js.map +1 -1
- package/dist/types/src/components/Panel/Panel.stories.d.ts +0 -3
- package/dist/types/src/components/Panel/Panel.stories.d.ts.map +1 -1
- package/dist/types/src/components/Panel/Panel.stories.js +1 -2
- package/dist/types/src/components/Panel/Panel.stories.js.map +1 -1
- package/dist/types/src/components/Viewport/Viewport.stories.js +1 -1
- package/dist/types/src/components/Viewport/Viewport.stories.js.map +1 -1
- package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
- package/dist/types/src/composites/Shell/Shell.js +4 -3
- package/dist/types/src/composites/Shell/Shell.js.map +1 -1
- package/dist/types/src/composites/Shell/run-shell.js +1 -1
- package/dist/types/src/composites/Shell/run-shell.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +7 -2
- package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +4 -4
- package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts +1 -1
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -1
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +10 -108
- package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -1
- package/dist/types/src/panels/IdentityPanel/useEdgeAgentsHandlers.d.ts +8 -0
- package/dist/types/src/panels/IdentityPanel/useEdgeAgentsHandlers.d.ts.map +1 -0
- package/dist/types/src/panels/IdentityPanel/useEdgeAgentsHandlers.js +84 -0
- package/dist/types/src/panels/IdentityPanel/useEdgeAgentsHandlers.js.map +1 -0
- package/dist/types/src/panels/IdentityPanel/useKubeAgentHandlers.d.ts +8 -0
- package/dist/types/src/panels/IdentityPanel/useKubeAgentHandlers.d.ts.map +1 -0
- package/dist/types/src/panels/IdentityPanel/useKubeAgentHandlers.js +119 -0
- package/dist/types/src/panels/IdentityPanel/useKubeAgentHandlers.js.map +1 -0
- package/dist/types/src/panels/JoinPanel/JoinPanel.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.js +24 -16
- package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts +3 -0
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js +3 -2
- package/dist/types/src/panels/JoinPanel/JoinPanel.stories.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts +7 -3
- package/dist/types/src/panels/JoinPanel/JoinPanelProps.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/joinMachine.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/joinMachine.js +2 -0
- package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts +3 -1
- package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js +9 -6
- package/dist/types/src/panels/JoinPanel/steps/InvitationAuthenticator.js.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts.map +1 -1
- package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js +8 -2
- package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js.map +1 -1
- package/dist/types/src/panels/Panels.stories.js +1 -1
- package/dist/types/src/panels/Panels.stories.js.map +1 -1
- package/dist/types/src/panels/SpacePanel/SpacePanel.js +1 -1
- package/dist/types/src/panels/SpacePanel/SpacePanel.js.map +1 -1
- package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js +1 -1
- package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js.map +1 -1
- package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts +4 -4
- package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts.map +1 -1
- package/dist/types/src/playwright/invitations-manager.d.ts +1 -1
- package/dist/types/src/playwright/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/playwright/invitations-manager.js +4 -10
- package/dist/types/src/playwright/invitations-manager.js.map +1 -1
- package/dist/types/src/playwright/invitations.spec.js +31 -32
- package/dist/types/src/playwright/invitations.spec.js.map +1 -1
- package/dist/types/src/playwright/playwright.config.d.ts +2 -2
- package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
- package/dist/types/src/playwright/playwright.config.js +12 -2
- package/dist/types/src/playwright/playwright.config.js.map +1 -1
- package/dist/types/src/testing/shell-manager.d.ts +1 -0
- package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
- package/dist/types/src/testing/shell-manager.js +2 -7
- package/dist/types/src/testing/shell-manager.js.map +1 -1
- package/dist/types/src/translations/locales/en-US.d.ts +1 -0
- package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
- package/dist/types/src/translations/locales/en-US.js +4 -3
- package/dist/types/src/translations/locales/en-US.js.map +1 -1
- package/package.json +29 -27
- package/src/components/CompoundButton/CompoundButton.stories.tsx +1 -1
- package/src/components/IdentityList/SpaceMemberList.stories.tsx +1 -2
- package/src/components/InvitationList/InvitationList.stories.tsx +1 -2
- package/src/components/Panel/Panel.stories.tsx +1 -2
- package/src/components/Viewport/Viewport.stories.tsx +1 -1
- package/src/composites/Shell/Shell.tsx +4 -3
- package/src/composites/Shell/run-shell.tsx +1 -1
- package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +7 -2
- package/src/panels/IdentityPanel/IdentityPanel.tsx +3 -3
- package/src/panels/IdentityPanel/IdentityPanelProps.ts +4 -4
- package/src/panels/IdentityPanel/useAgentHandlers.ts +9 -114
- package/src/panels/IdentityPanel/useEdgeAgentsHandlers.ts +96 -0
- package/src/panels/IdentityPanel/useKubeAgentHandlers.ts +128 -0
- package/src/panels/JoinPanel/JoinPanel.stories.tsx +3 -2
- package/src/panels/JoinPanel/JoinPanel.tsx +31 -9
- package/src/panels/JoinPanel/JoinPanelProps.ts +7 -3
- package/src/panels/JoinPanel/joinMachine.ts +2 -0
- package/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx +29 -16
- package/src/panels/JoinPanel/steps/InvitationInput.tsx +9 -17
- package/src/panels/Panels.stories.tsx +1 -1
- package/src/panels/SpacePanel/SpacePanel.stories.tsx +1 -1
- package/src/panels/SpacePanel/SpacePanel.tsx +3 -3
- package/src/panels/SpacePanel/SpacePanelProps.ts +4 -4
- package/src/playwright/invitations-manager.ts +4 -8
- package/src/playwright/invitations.spec.ts +32 -33
- package/src/playwright/playwright.config.ts +13 -2
- package/src/testing/shell-manager.ts +4 -9
- package/src/translations/locales/en-US.ts +4 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type cloneElement } from 'react';
|
|
5
|
+
import { type FC, type cloneElement } from 'react';
|
|
6
6
|
|
|
7
7
|
import type { Identity } from '@dxos/react-client/halo';
|
|
8
8
|
import type { Invitation, AuthenticatingInvitationObservable, InvitationResult } from '@dxos/react-client/invitations';
|
|
@@ -55,6 +55,10 @@ export type JoinPanelImplProps = Pick<
|
|
|
55
55
|
Halo: Invitation.State;
|
|
56
56
|
Space: Invitation.State;
|
|
57
57
|
}>;
|
|
58
|
+
invitationAuthMethods?: Partial<{
|
|
59
|
+
Halo: Invitation.AuthMethod;
|
|
60
|
+
Space: Invitation.AuthMethod;
|
|
61
|
+
}>;
|
|
58
62
|
succeededKeys?: Partial<{
|
|
59
63
|
Halo: Set<string>;
|
|
60
64
|
Space: Set<string>;
|
|
@@ -71,8 +75,8 @@ export type JoinPanelImplProps = Pick<
|
|
|
71
75
|
onSpaceInvitationAuthenticate?: (authCode: string) => Promise<void> | undefined;
|
|
72
76
|
onConfirmResetStorage?: () => Promise<void>;
|
|
73
77
|
onCancelResetStorage?: () => void;
|
|
74
|
-
IdentityInput?:
|
|
75
|
-
ConfirmReset?:
|
|
78
|
+
IdentityInput?: FC<IdentityInputProps>;
|
|
79
|
+
ConfirmReset?: FC<ConfirmResetProps>;
|
|
76
80
|
};
|
|
77
81
|
|
|
78
82
|
export interface IdentityAction {
|
|
@@ -316,6 +316,7 @@ const joinMachine = createMachine<JoinMachineContext, JoinEvent>(
|
|
|
316
316
|
{ target: 'acceptingSpaceInvitation', actions: 'log' },
|
|
317
317
|
],
|
|
318
318
|
},
|
|
319
|
+
// TODO(wittjosiah): Remove.
|
|
319
320
|
choosingIdentity: {
|
|
320
321
|
initial: 'unknownAuthMethod',
|
|
321
322
|
states: {
|
|
@@ -343,6 +344,7 @@ const joinMachine = createMachine<JoinMachineContext, JoinEvent>(
|
|
|
343
344
|
deselectAuthMethod: { target: '.choosingAuthMethod', actions: 'log' },
|
|
344
345
|
},
|
|
345
346
|
},
|
|
347
|
+
// TODO(wittjosiah): Factor out to a machine handling recovery and device invitations.
|
|
346
348
|
resettingIdentity: {},
|
|
347
349
|
acceptingSpaceInvitation: acceptingInvitationTemplate('Space', '#join.finishingJoiningSpace'),
|
|
348
350
|
finishingJoiningSpace: {
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { type ChangeEvent, useState } from 'react';
|
|
6
6
|
|
|
7
|
+
import { Invitation } from '@dxos/react-client/invitations';
|
|
7
8
|
import { Input, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { descriptionText } from '@dxos/react-ui-theme';
|
|
8
10
|
import { hexToEmoji } from '@dxos/util';
|
|
9
11
|
|
|
10
12
|
import { Actions, Action, Emoji, StepHeading, Label } from '../../../components';
|
|
@@ -14,6 +16,7 @@ const pinLength = 6;
|
|
|
14
16
|
|
|
15
17
|
export interface InvitationAuthenticatorProps extends JoinStepProps {
|
|
16
18
|
Kind: 'Space' | 'Halo';
|
|
19
|
+
authMethod?: Invitation.AuthMethod;
|
|
17
20
|
failed?: boolean;
|
|
18
21
|
pending?: boolean;
|
|
19
22
|
invitationId?: string;
|
|
@@ -24,6 +27,7 @@ export interface InvitationAuthenticatorProps extends JoinStepProps {
|
|
|
24
27
|
export const InvitationAuthenticator = ({
|
|
25
28
|
failed,
|
|
26
29
|
Kind,
|
|
30
|
+
authMethod,
|
|
27
31
|
active,
|
|
28
32
|
pending,
|
|
29
33
|
invitationId,
|
|
@@ -51,22 +55,31 @@ export const InvitationAuthenticator = ({
|
|
|
51
55
|
})}
|
|
52
56
|
>
|
|
53
57
|
<Input.Label asChild>
|
|
54
|
-
|
|
58
|
+
{authMethod === Invitation.AuthMethod.SHARED_SECRET ? (
|
|
59
|
+
<StepHeading>{t('auth code input label')}</StepHeading>
|
|
60
|
+
) : (
|
|
61
|
+
<>
|
|
62
|
+
<StepHeading className={descriptionText}>{t('authenticating label')}</StepHeading>
|
|
63
|
+
<div role='none' className='grow' />
|
|
64
|
+
</>
|
|
65
|
+
)}
|
|
55
66
|
</Input.Label>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
{authMethod === Invitation.AuthMethod.SHARED_SECRET && (
|
|
68
|
+
<Input.PinInput
|
|
69
|
+
{...{
|
|
70
|
+
disabled,
|
|
71
|
+
length: pinLength,
|
|
72
|
+
onChange,
|
|
73
|
+
inputMode: 'numeric',
|
|
74
|
+
autoComplete: 'off',
|
|
75
|
+
pattern: '\\d*',
|
|
76
|
+
'data-autofocus': `connecting${Kind}Invitation inputting${Kind}VerificationCode authenticationFailing${Kind}VerificationCode authenticating${Kind}VerificationCode`,
|
|
77
|
+
'data-prevent-ios-autofocus': true,
|
|
78
|
+
'data-testid': `${invitationType}-auth-code-input`,
|
|
79
|
+
'data-1p-ignore': true,
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
)}
|
|
70
83
|
{failed && (
|
|
71
84
|
<Input.DescriptionAndValidation classNames='text-center'>
|
|
72
85
|
<Input.Validation>{t('failed to authenticate message')}</Input.Validation>
|
|
@@ -74,7 +87,7 @@ export const InvitationAuthenticator = ({
|
|
|
74
87
|
)}
|
|
75
88
|
</Input.Root>
|
|
76
89
|
|
|
77
|
-
{invitationId && (
|
|
90
|
+
{invitationId && authMethod === Invitation.AuthMethod.SHARED_SECRET && (
|
|
78
91
|
<>
|
|
79
92
|
<Label>{t('auth other device emoji message')}</Label>
|
|
80
93
|
<div className='flex justify-center'>
|
|
@@ -78,25 +78,17 @@ export const InvitationInput = (props: InvitationInputProps) => {
|
|
|
78
78
|
/>
|
|
79
79
|
</div>
|
|
80
80
|
<Actions>
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
</Action>
|
|
90
|
-
) : exitActionParent ? (
|
|
91
|
-
cloneElement(exitActionParent, {}, exitAction)
|
|
92
|
-
) : doneActionParent ? (
|
|
93
|
-
cloneElement(doneActionParent, {}, exitAction)
|
|
94
|
-
) : (
|
|
95
|
-
exitAction
|
|
96
|
-
)}
|
|
81
|
+
{/* TODO(wittjosiah): This disables returning to deprecated identity creation flow. */}
|
|
82
|
+
{Kind === 'Halo'
|
|
83
|
+
? null
|
|
84
|
+
: exitActionParent
|
|
85
|
+
? cloneElement(exitActionParent, {}, exitAction)
|
|
86
|
+
: doneActionParent
|
|
87
|
+
? cloneElement(doneActionParent, {}, exitAction)
|
|
88
|
+
: exitAction}
|
|
97
89
|
<Action
|
|
98
90
|
variant='primary'
|
|
99
|
-
disabled={disabled}
|
|
91
|
+
disabled={disabled || inputValue.trim().length === 0}
|
|
100
92
|
onClick={handleNext}
|
|
101
93
|
data-testid={`${Kind.toLowerCase()}-invitation-input-continue`}
|
|
102
94
|
>
|
|
@@ -53,7 +53,7 @@ export const Default = (props: any) => {
|
|
|
53
53
|
Default.parameters = { layout: 'fullscreen' };
|
|
54
54
|
|
|
55
55
|
export default {
|
|
56
|
-
title: 'react-shell/All',
|
|
56
|
+
title: 'sdk/react-shell/All',
|
|
57
57
|
decorators: [withTheme],
|
|
58
58
|
component: StoryRow,
|
|
59
59
|
parameters: { chromatic: { disableSnapshot: false }, translations: [osTranslations] },
|
|
@@ -28,7 +28,7 @@ const noOpProps: SpacePanelImplProps = {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export default {
|
|
31
|
-
title: 'react-shell/SpacePanel',
|
|
31
|
+
title: 'sdk/react-shell/SpacePanel',
|
|
32
32
|
component: SpacePanelImpl,
|
|
33
33
|
decorators: [withTheme],
|
|
34
34
|
parameters: { chromatic: { disableSnapshot: false } },
|
|
@@ -8,7 +8,7 @@ import React, { useEffect, useMemo } from 'react';
|
|
|
8
8
|
import { log } from '@dxos/log';
|
|
9
9
|
import { useInvitationStatus } from '@dxos/react-client/invitations';
|
|
10
10
|
import type { CancellableInvitationObservable } from '@dxos/react-client/invitations';
|
|
11
|
-
import {
|
|
11
|
+
import { useId, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
|
|
13
13
|
import { type SpacePanelHeadingProps, type SpacePanelImplProps, type SpacePanelProps } from './SpacePanelProps';
|
|
14
14
|
import { useSpaceMachine } from './spaceMachine';
|
|
@@ -46,7 +46,7 @@ export const SpacePanelImpl = (props: SpacePanelImplProps) => {
|
|
|
46
46
|
} = props;
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
|
|
49
|
+
<>
|
|
50
50
|
<SpacePanelHeading {...rest} {...{ titleId, space }} />
|
|
51
51
|
<Viewport.Root activeView={activeView}>
|
|
52
52
|
<Viewport.Views>
|
|
@@ -62,7 +62,7 @@ export const SpacePanelImpl = (props: SpacePanelImplProps) => {
|
|
|
62
62
|
</Viewport.View>
|
|
63
63
|
</Viewport.Views>
|
|
64
64
|
</Viewport.Root>
|
|
65
|
-
|
|
65
|
+
</>
|
|
66
66
|
);
|
|
67
67
|
};
|
|
68
68
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type cloneElement } from 'react';
|
|
5
|
+
import { type FC, type cloneElement } from 'react';
|
|
6
6
|
import { type SingleOrArray, type Event } from 'xstate';
|
|
7
7
|
|
|
8
8
|
import { type Space } from '@dxos/react-client/echo';
|
|
@@ -23,9 +23,9 @@ export type SpacePanelImplProps = {
|
|
|
23
23
|
authCode?: string;
|
|
24
24
|
onDone?: () => void;
|
|
25
25
|
doneActionParent?: Parameters<typeof cloneElement>[0];
|
|
26
|
-
DoneAction?:
|
|
27
|
-
SpaceManager?:
|
|
28
|
-
InvitationManager?:
|
|
26
|
+
DoneAction?: FC;
|
|
27
|
+
SpaceManager?: FC<SpaceManagerProps>;
|
|
28
|
+
InvitationManager?: FC<InvitationManagerProps>;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export type SpacePanelProps = Pick<SpacePanelImplProps, 'space'> &
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type
|
|
6
|
-
import { expect } from 'chai';
|
|
7
|
-
import waitForExpect from 'wait-for-expect';
|
|
5
|
+
import { expect, type Browser, type ConsoleMessage } from '@playwright/test';
|
|
8
6
|
|
|
9
7
|
import { Trigger } from '@dxos/async';
|
|
10
8
|
import { type Invitation } from '@dxos/react-client/invitations';
|
|
11
9
|
import { ConnectionState } from '@dxos/react-client/mesh';
|
|
12
|
-
import { setupPage } from '@dxos/test/playwright';
|
|
10
|
+
import { setupPage } from '@dxos/test-utils/playwright';
|
|
13
11
|
|
|
14
12
|
import { ScopedShellManager } from '../testing';
|
|
15
13
|
|
|
@@ -35,11 +33,11 @@ export class InvitationsManager extends ScopedShellManager {
|
|
|
35
33
|
|
|
36
34
|
const { page } = await setupPage(this._browser, {
|
|
37
35
|
url: storybookUrl('invitations--default'),
|
|
38
|
-
waitFor: (page) => page.getByTestId('invitations.identity-header').first().isVisible(),
|
|
39
36
|
});
|
|
40
37
|
|
|
41
38
|
this.page = page;
|
|
42
39
|
this.page.on('console', (message) => this._onConsoleMessage(message));
|
|
40
|
+
await this.page.getByTestId('invitations.identity-header').first().waitFor({ state: 'visible' });
|
|
43
41
|
this._initialized = true;
|
|
44
42
|
}
|
|
45
43
|
|
|
@@ -119,9 +117,7 @@ export class InvitationsManager extends ScopedShellManager {
|
|
|
119
117
|
const createIdentity = this.peer(id).getByTestId('invitations.create-identity');
|
|
120
118
|
// TODO(wittjosiah): Clicking on buttons wrapped in tooltips is flaky in webkit playwright.
|
|
121
119
|
await createIdentity.click();
|
|
122
|
-
await
|
|
123
|
-
expect(await createIdentity.isDisabled()).to.be.true;
|
|
124
|
-
});
|
|
120
|
+
await expect(createIdentity).toBeDisabled();
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
async createSpace(id: number) {
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { test } from '@playwright/test';
|
|
6
|
-
import { expect } from 'chai';
|
|
5
|
+
import { expect, test } from '@playwright/test';
|
|
7
6
|
|
|
8
7
|
import { sleep } from '@dxos/async';
|
|
9
8
|
import { Invitation } from '@dxos/react-client/invitations';
|
|
@@ -47,7 +46,7 @@ test.describe('Invitations', () => {
|
|
|
47
46
|
await manager.authenticateInvitation('device', authCode, manager.peer(1));
|
|
48
47
|
await manager.doneInvitation('device', manager.peer(1));
|
|
49
48
|
|
|
50
|
-
expect(await manager.getDisplayName(0)).
|
|
49
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
test('no auth method', async () => {
|
|
@@ -59,7 +58,7 @@ test.describe('Invitations', () => {
|
|
|
59
58
|
await manager.acceptInvitation(1, 'device', invitation);
|
|
60
59
|
await manager.doneInvitation('device', manager.peer(1));
|
|
61
60
|
|
|
62
|
-
expect(await manager.getDisplayName(0)).
|
|
61
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
63
62
|
});
|
|
64
63
|
|
|
65
64
|
test('invalid & retry auth code', async () => {
|
|
@@ -75,7 +74,7 @@ test.describe('Invitations', () => {
|
|
|
75
74
|
await manager.authenticateInvitation('device', authCode, manager.peer(1));
|
|
76
75
|
await manager.doneInvitation('device', manager.peer(1));
|
|
77
76
|
|
|
78
|
-
expect(await manager.getDisplayName(0)).
|
|
77
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
// TODO(wittjosiah): Remove? This seems to invalidate the invitation now.
|
|
@@ -94,7 +93,7 @@ test.describe('Invitations', () => {
|
|
|
94
93
|
await manager.clearAuthCode('device', manager.peer(1));
|
|
95
94
|
await manager.authenticateInvitation('device', '000003', manager.peer(1));
|
|
96
95
|
|
|
97
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
96
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
98
97
|
|
|
99
98
|
await manager.resetInvitation(manager.peer(1));
|
|
100
99
|
await manager.invitationInputContinue('device', manager.peer(1));
|
|
@@ -102,7 +101,7 @@ test.describe('Invitations', () => {
|
|
|
102
101
|
await manager.authenticateInvitation('device', authCode, manager.peer(1));
|
|
103
102
|
await manager.doneInvitation('device', manager.peer(1));
|
|
104
103
|
|
|
105
|
-
expect(await manager.getDisplayName(0)).
|
|
104
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
106
105
|
});
|
|
107
106
|
|
|
108
107
|
test('invitation timeout', async () => {
|
|
@@ -113,7 +112,7 @@ test.describe('Invitations', () => {
|
|
|
113
112
|
await manager.openPanel(1, 'identity');
|
|
114
113
|
await manager.acceptInvitation(1, 'device', invitation);
|
|
115
114
|
|
|
116
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
115
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
117
116
|
});
|
|
118
117
|
|
|
119
118
|
// TODO(thure): This is skipped because the UI no longer affords cancelling device invitations, consider removing.
|
|
@@ -125,10 +124,10 @@ test.describe('Invitations', () => {
|
|
|
125
124
|
|
|
126
125
|
await manager.openPanel(1, 'identity');
|
|
127
126
|
await manager.acceptInvitation(1, 'device', invitation);
|
|
128
|
-
expect(await manager.readyToAuthenticate('device', manager.peer(1))).
|
|
127
|
+
expect(await manager.readyToAuthenticate('device', manager.peer(1))).toBe(true);
|
|
129
128
|
await manager.cancelInvitation('device', 'host', manager.peer(0));
|
|
130
129
|
|
|
131
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
130
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
132
131
|
});
|
|
133
132
|
|
|
134
133
|
// TODO(wittjosiah): Remove? This seems to invalidate the invitation now.
|
|
@@ -147,7 +146,7 @@ test.describe('Invitations', () => {
|
|
|
147
146
|
await manager.authenticateInvitation('device', authCode, manager.peer(1));
|
|
148
147
|
await manager.doneInvitation('device', manager.peer(1));
|
|
149
148
|
|
|
150
|
-
expect(await manager.getDisplayName(0)).
|
|
149
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
151
150
|
});
|
|
152
151
|
|
|
153
152
|
// TODO(thure): The design no longer affords signalling an identity’s network status. Remove or adjust test, or adjust design.
|
|
@@ -159,18 +158,18 @@ test.describe('Invitations', () => {
|
|
|
159
158
|
|
|
160
159
|
await manager.openPanel(1, 'identity');
|
|
161
160
|
await manager.acceptInvitation(1, 'device', invitation);
|
|
162
|
-
expect(await manager.readyToAuthenticate('device', manager.peer(1))).
|
|
161
|
+
expect(await manager.readyToAuthenticate('device', manager.peer(1))).toBe(true);
|
|
163
162
|
await manager.toggleNetworkStatus(0);
|
|
164
|
-
expect(await manager.getNetworkStatus(0)).
|
|
163
|
+
expect(await manager.getNetworkStatus(0)).toEqual(ConnectionState.OFFLINE);
|
|
165
164
|
await manager.toggleNetworkStatus(0);
|
|
166
|
-
expect(await manager.getNetworkStatus(0)).
|
|
165
|
+
expect(await manager.getNetworkStatus(0)).toEqual(ConnectionState.ONLINE);
|
|
167
166
|
await manager.resetInvitation(manager.peer(1));
|
|
168
167
|
await manager.invitationInputContinue('device', manager.peer(1));
|
|
169
168
|
await manager.clearAuthCode('device', manager.peer(1));
|
|
170
169
|
await manager.authenticateInvitation('device', authCode, manager.peer(1));
|
|
171
170
|
await manager.doneInvitation('device', manager.peer(1));
|
|
172
171
|
|
|
173
|
-
expect(await manager.getDisplayName(0)).
|
|
172
|
+
expect(await manager.getDisplayName(0)).toEqual(await manager.getDisplayName(1));
|
|
174
173
|
});
|
|
175
174
|
});
|
|
176
175
|
|
|
@@ -190,7 +189,7 @@ test.describe('Invitations', () => {
|
|
|
190
189
|
await manager.doneInvitation('space', manager.peer(1));
|
|
191
190
|
|
|
192
191
|
await manager.openPanel(0, 'spaces');
|
|
193
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
192
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
194
193
|
});
|
|
195
194
|
|
|
196
195
|
test('already joined', async () => {
|
|
@@ -209,7 +208,7 @@ test.describe('Invitations', () => {
|
|
|
209
208
|
await manager.acceptInvitation(1, 'space', invitation2);
|
|
210
209
|
await manager.doneInvitation('space', manager.peer(1));
|
|
211
210
|
|
|
212
|
-
expect(await manager.getSpaceMembersCount(0)).
|
|
211
|
+
expect(await manager.getSpaceMembersCount(0)).toEqual(2);
|
|
213
212
|
});
|
|
214
213
|
|
|
215
214
|
test('no auth method', async () => {
|
|
@@ -224,7 +223,7 @@ test.describe('Invitations', () => {
|
|
|
224
223
|
await manager.doneInvitation('space', manager.peer(1));
|
|
225
224
|
|
|
226
225
|
await manager.openPanel(0, 'spaces');
|
|
227
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
226
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
228
227
|
});
|
|
229
228
|
|
|
230
229
|
test('invalid & retry auth code', async () => {
|
|
@@ -239,14 +238,14 @@ test.describe('Invitations', () => {
|
|
|
239
238
|
await manager.acceptInvitation(1, 'space', invitation);
|
|
240
239
|
await manager.authenticateInvitation('space', '000000', manager.peer(1));
|
|
241
240
|
|
|
242
|
-
expect(await manager.authenticatorIsVisible('space', manager.peer(1))).
|
|
241
|
+
expect(await manager.authenticatorIsVisible('space', manager.peer(1))).toBe(true);
|
|
243
242
|
|
|
244
243
|
await manager.clearAuthCode('space', manager.peer(1));
|
|
245
244
|
await manager.authenticateInvitation('space', authCode, manager.peer(1));
|
|
246
245
|
await manager.doneInvitation('space', manager.peer(1));
|
|
247
246
|
|
|
248
247
|
await manager.openPanel(0, 'spaces');
|
|
249
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
248
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
250
249
|
});
|
|
251
250
|
|
|
252
251
|
// TODO(wittjosiah): Remove? This seems to invalidate the invitation now.
|
|
@@ -267,7 +266,7 @@ test.describe('Invitations', () => {
|
|
|
267
266
|
await manager.clearAuthCode('space', manager.peer(1));
|
|
268
267
|
await manager.authenticateInvitation('space', '000003', manager.peer(1));
|
|
269
268
|
|
|
270
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
269
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
271
270
|
|
|
272
271
|
await manager.resetInvitation(manager.peer(1));
|
|
273
272
|
await manager.invitationInputContinue('space', manager.peer(1));
|
|
@@ -276,7 +275,7 @@ test.describe('Invitations', () => {
|
|
|
276
275
|
await manager.doneInvitation('space', manager.peer(1));
|
|
277
276
|
|
|
278
277
|
await manager.openPanel(0, 'spaces');
|
|
279
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
278
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
280
279
|
});
|
|
281
280
|
|
|
282
281
|
test('invitation timeout', async () => {
|
|
@@ -289,7 +288,7 @@ test.describe('Invitations', () => {
|
|
|
289
288
|
await manager.openPanel(1, 'join');
|
|
290
289
|
await manager.acceptInvitation(1, 'space', invitation);
|
|
291
290
|
|
|
292
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
291
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
293
292
|
});
|
|
294
293
|
|
|
295
294
|
// TODO(wittjosiah): Cancel not propagating.
|
|
@@ -302,10 +301,10 @@ test.describe('Invitations', () => {
|
|
|
302
301
|
await manager.createIdentity(1);
|
|
303
302
|
await manager.openPanel(1, 'join');
|
|
304
303
|
await manager.acceptInvitation(1, 'space', invitation);
|
|
305
|
-
expect(await manager.readyToAuthenticate('space', manager.peer(1))).
|
|
304
|
+
expect(await manager.readyToAuthenticate('space', manager.peer(1))).toBe(true);
|
|
306
305
|
await manager.cancelInvitation('space', 'host', manager.peer(0));
|
|
307
306
|
|
|
308
|
-
expect(await manager.invitationFailed(manager.peer(1))).
|
|
307
|
+
expect(await manager.invitationFailed(manager.peer(1))).toBe(true);
|
|
309
308
|
});
|
|
310
309
|
|
|
311
310
|
// TODO(wittjosiah): Remove? This seems to invalidate the invitation now.
|
|
@@ -327,7 +326,7 @@ test.describe('Invitations', () => {
|
|
|
327
326
|
await manager.doneInvitation('space', manager.peer(1));
|
|
328
327
|
|
|
329
328
|
await manager.openPanel(0, 'spaces');
|
|
330
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
329
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
331
330
|
});
|
|
332
331
|
|
|
333
332
|
// TODO(thure): The design no longer affords signalling an identity’s network status. Remove or adjust test, or adjust design.
|
|
@@ -341,11 +340,11 @@ test.describe('Invitations', () => {
|
|
|
341
340
|
await manager.createIdentity(1);
|
|
342
341
|
await manager.openPanel(1, 'join');
|
|
343
342
|
await manager.acceptInvitation(1, 'space', invitation);
|
|
344
|
-
expect(await manager.readyToAuthenticate('space', manager.peer(1))).
|
|
343
|
+
expect(await manager.readyToAuthenticate('space', manager.peer(1))).toBe(true);
|
|
345
344
|
await manager.toggleNetworkStatus(0);
|
|
346
|
-
expect(await manager.getNetworkStatus(0)).
|
|
345
|
+
expect(await manager.getNetworkStatus(0)).toEqual(ConnectionState.OFFLINE);
|
|
347
346
|
await manager.toggleNetworkStatus(0);
|
|
348
|
-
expect(await manager.getNetworkStatus(0)).
|
|
347
|
+
expect(await manager.getNetworkStatus(0)).toEqual(ConnectionState.ONLINE);
|
|
349
348
|
await manager.resetInvitation(manager.peer(1));
|
|
350
349
|
await manager.invitationInputContinue('space', manager.peer(1));
|
|
351
350
|
await manager.clearAuthCode('space', manager.peer(1));
|
|
@@ -353,7 +352,7 @@ test.describe('Invitations', () => {
|
|
|
353
352
|
await manager.doneInvitation('space', manager.peer(1));
|
|
354
353
|
|
|
355
354
|
await manager.openPanel(0, 'spaces');
|
|
356
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
355
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
357
356
|
});
|
|
358
357
|
|
|
359
358
|
test('multiple concurrent invitations', async () => {
|
|
@@ -385,9 +384,9 @@ test.describe('Invitations', () => {
|
|
|
385
384
|
await manager.doneInvitation('space', manager.peer(2));
|
|
386
385
|
|
|
387
386
|
await manager.openPanel(0, 'spaces');
|
|
388
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
389
|
-
expect(await manager.getSpaceName(0, 1)).
|
|
390
|
-
expect(await manager.getSpaceName(1, 1)).
|
|
387
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(1, 1));
|
|
388
|
+
expect(await manager.getSpaceName(0, 1)).toEqual(await manager.getSpaceName(2, 1));
|
|
389
|
+
expect(await manager.getSpaceName(1, 1)).toEqual(await manager.getSpaceName(2, 1));
|
|
391
390
|
});
|
|
392
391
|
});
|
|
393
392
|
});
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { nxE2EPreset } from '@nx/playwright/preset';
|
|
6
|
+
import { defineConfig } from '@playwright/test';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
import { e2ePreset } from '@dxos/test-utils/playwright';
|
|
9
|
+
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
...nxE2EPreset(__filename, { testDir: __dirname }),
|
|
12
|
+
...e2ePreset(__dirname),
|
|
13
|
+
webServer: {
|
|
14
|
+
command: 'pnpm -w nx storybook-e2e stories',
|
|
15
|
+
port: 9009,
|
|
16
|
+
reuseExistingServer: !process.env.CI,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type { ConsoleMessage,
|
|
5
|
+
import type { ConsoleMessage, Page } from '@playwright/test';
|
|
6
6
|
|
|
7
7
|
import { sleep, Trigger } from '@dxos/async';
|
|
8
8
|
|
|
@@ -60,13 +60,6 @@ export class ShellManager extends ScopedShellManager {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
async resetDevice() {
|
|
63
|
-
const handleDialog = async (dialog: Dialog) => {
|
|
64
|
-
if (dialog.type() === 'confirm') {
|
|
65
|
-
await dialog.accept();
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
this.page.on('dialog', handleDialog);
|
|
69
|
-
|
|
70
63
|
await this.shell.getByTestId('device-list-item-current.options').click();
|
|
71
64
|
await this.shell.getByTestId('device-list-item-current.reset').click();
|
|
72
65
|
await this.shell.getByTestId('reset-storage.reset-identity-input').fill(CONFIRM_INPUT);
|
|
@@ -78,6 +71,9 @@ export class ShellManager extends ScopedShellManager {
|
|
|
78
71
|
await this.shell.getByTestId('device-list-item-current.join-existing').click();
|
|
79
72
|
await this.shell.getByTestId('join-new-identity.reset-identity-input').fill(CONFIRM_INPUT);
|
|
80
73
|
await this.shell.getByTestId('join-new-identity.reset-identity-confirm').click();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async acceptDeviceInvitation(invitationCode: string) {
|
|
81
77
|
await this.inputInvitation('device', invitationCode, this.shell);
|
|
82
78
|
}
|
|
83
79
|
|
|
@@ -114,7 +110,6 @@ export class ShellManager extends ScopedShellManager {
|
|
|
114
110
|
// Wait for focus to shift before typing.
|
|
115
111
|
await sleep(1500);
|
|
116
112
|
await this.authenticateInvitation('space', authCode, this.shell);
|
|
117
|
-
await this.doneInvitation('space', this.shell);
|
|
118
113
|
}
|
|
119
114
|
|
|
120
115
|
private async _onConsoleMessage(message: ConsoleMessage) {
|
|
@@ -34,7 +34,7 @@ export const os = {
|
|
|
34
34
|
'recover identity input label': 'Type or paste your seed phrase',
|
|
35
35
|
'failed to create identity message': 'Failed to create an identity.',
|
|
36
36
|
'failed to recover identity message': 'Failed to recover an identity from the provided seed phrase.',
|
|
37
|
-
'failed to authenticate message': 'Incorrect
|
|
37
|
+
'failed to authenticate message': 'Incorrect code.',
|
|
38
38
|
'identity added label': 'Created identity & added to this device:',
|
|
39
39
|
'join space as identity heading': '<part>as </part><part><icon/><label>{{labelValue}}</label></part>',
|
|
40
40
|
'error status label': 'Failed',
|
|
@@ -42,8 +42,8 @@ export const os = {
|
|
|
42
42
|
'cancelled status label': 'Cancelled',
|
|
43
43
|
'init status label': 'Ready to connect',
|
|
44
44
|
'connecting status label': 'Connecting…',
|
|
45
|
-
'connected status label': 'Enter
|
|
46
|
-
'authenticating status label': 'Enter
|
|
45
|
+
'connected status label': 'Enter authentication code',
|
|
46
|
+
'authenticating status label': 'Enter authentication code',
|
|
47
47
|
'success status label': 'Success',
|
|
48
48
|
'cancel label': 'Cancel',
|
|
49
49
|
'done label': 'Done',
|
|
@@ -152,4 +152,5 @@ export const os = {
|
|
|
152
152
|
'agent requested label': 'Agent requested',
|
|
153
153
|
'agent requested description':
|
|
154
154
|
'The agent service is creating an agent for you. Once the agent connects, it will display in the devices list.',
|
|
155
|
+
'authenticating label': 'Authenticating…',
|
|
155
156
|
};
|