Skip to content

Commit

Permalink
Added support for setting randomSeed & randomValue properties for…
Browse files Browse the repository at this point in the history
… transcript testing (#2209)

* Added UI to allow users to send an initial SetTestOptions event to enable transcript-driven testing.

* Updated changelog
  • Loading branch information
tonyanziano authored Dec 3, 2020
1 parent 343c26d commit 1a9973e
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"outputCapture": "std",
"internalConsoleOptions": "openOnSessionStart",
"cwd": "${workspaceFolder}/packages/app/main",
"outFiles": [ "${workspaceRoot}/packages/app/main/app/server/*" ]
"outFiles": [ "${workspaceRoot}/packages/app/main/app/**/*.js"]
},
{
"type": "node",
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
- [client/main] Added UI to open bot dialog that allows the user to set transcript testing properties `randomSeed` and `randomValue` in PR [2209](https://github.com/microsoft/BotFramework-Emulator/pull/2209)

## v4.11.0 - 2020 - 11 - 05
- [client] Moved from master to main as the default branch. [2194](https://github.com/microsoft/BotFramework-Emulator/pull/2194)
- [client] Updated support for new activity middleware contract provided by Web Chat. [2202](https://github.com/microsoft/BotFramework-Emulator/pull/2202)
Expand Down
10 changes: 9 additions & 1 deletion packages/app/client/src/state/sagas/botSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ export class BotSagas {
mode: action.payload.mode,
msaAppId: action.payload.appId,
msaPassword: action.payload.appPassword,
randomSeed: action.payload.randomSeed,
randomValue: action.payload.randomValue,
speechKey: action.payload.speechKey,
speechRegion: action.payload.speechRegion,
user,
Expand All @@ -153,7 +155,13 @@ export class BotSagas {

// send CU or debug INSPECT message
if (!(action.payload.speechKey && action.payload.speechRegion)) {
res = yield ChatSagas.sendInitialActivity({ conversationId, members, mode: action.payload.mode });
res = yield ChatSagas.sendInitialActivities({
conversationId,
members,
mode: action.payload.mode,
randomSeed: action.payload.randomSeed,
randomValue: action.payload.randomValue,
});
if (!res.ok) {
yield* throwErrorFromResponse('Error occurred while sending the initial activity', res);
}
Expand Down
44 changes: 36 additions & 8 deletions packages/app/client/src/state/sagas/chatSagas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,9 +754,9 @@ describe('The ChatSagas,', () => {
)
);

// call sendInitialActivity
// call sendInitialActivities
expect(gen.next({ ok: true }).value).toEqual(
call([ChatSagas, ChatSagas.sendInitialActivity], { conversationId, members: json.members, mode: chat.mode })
call([ChatSagas, ChatSagas.sendInitialActivities], { conversationId, members: json.members, mode: chat.mode })
);

// put updatePendingSpeechTokenRetrieval
Expand Down Expand Up @@ -889,9 +889,9 @@ describe('The ChatSagas,', () => {
)
);

// call sendInitialActivity
// call sendInitialActivities
expect(gen.next({ ok: true }).value).toEqual(
call([ChatSagas, ChatSagas.sendInitialActivity], { conversationId, members: json.members, mode: chat.mode })
call([ChatSagas, ChatSagas.sendInitialActivities], { conversationId, members: json.members, mode: chat.mode })
);

// put updatePendingSpeechTokenRetrieval
Expand Down Expand Up @@ -1114,13 +1114,41 @@ describe('The ChatSagas,', () => {
});
});

it('should send a SetTestOptions event activity for non-debug mode conversations', () => {
const payload = {
conversationId: 'someConvoId',
members: [],
mode: 'livechat' as EmulatorMode,
randomSeed: 123,
randomValue: 456,
};
const gen = ChatSagas.sendInitialActivities(payload);

// select server url
expect(gen.next().value).toEqual(select(getServerUrl));

// call sendActivityToBot
const serverUrl = 'http://localhost:58267';
const activity = {
name: 'SetTestOptions',
type: 'event',
value: {
randomSeed: payload.randomSeed,
randomValue: payload.randomValue,
},
};
expect(gen.next(serverUrl).value).toEqual(
call([ConversationService, ConversationService.sendActivityToBot], serverUrl, payload.conversationId, activity)
);
});

it('should send a conversation update for non-debug mode conversations', () => {
const payload = {
conversationId: 'someConvoId',
members: [],
mode: 'livechat',
mode: 'livechat' as EmulatorMode,
};
const gen = ChatSagas.sendInitialActivity(payload);
const gen = ChatSagas.sendInitialActivities(payload);

// select server url
expect(gen.next().value).toEqual(select(getServerUrl));
Expand All @@ -1141,9 +1169,9 @@ describe('The ChatSagas,', () => {
const payload = {
conversationId: 'someConvoId',
members: [],
mode: 'debug',
mode: 'debug' as EmulatorMode,
};
const gen = ChatSagas.sendInitialActivity(payload);
const gen = ChatSagas.sendInitialActivities(payload);

// select server url
expect(gen.next().value).toEqual(select(getServerUrl));
Expand Down
49 changes: 45 additions & 4 deletions packages/app/client/src/state/sagas/chatSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,21 @@ interface BootstrapChatPayload {
mode: EmulatorMode;
msaAppId?: string;
msaPassword?: string;
randomSeed?: number;
randomValue?: number;
speechKey?: string;
speechRegion?: string;
user: User;
}

interface InitialActivitiesPayload {
conversationId: string;
members: any[];
mode: EmulatorMode;
randomSeed?: number;
randomValue?: number;
}

export class ChatSagas {
@CommandServiceInstance()
private static commandService: CommandServiceImpl;
Expand Down Expand Up @@ -386,6 +396,8 @@ export class ChatSagas {
msaAppId,
msaPassword,
user,
randomSeed,
randomValue,
speechKey,
speechRegion,
} = payload;
Expand Down Expand Up @@ -417,6 +429,8 @@ export class ChatSagas {
conversationId,
directLine,
userId: user.id,
randomSeed,
randomValue,
speechKey,
speechRegion,
})
Expand Down Expand Up @@ -570,6 +584,8 @@ export class ChatSagas {
newChat(documentId, chat.mode, {
conversationId,
directLine,
randomSeed: chat.randomSeed,
randomValue: chat.randomValue,
speechKey: chat.speechKey,
speechRegion: chat.speechRegion,
userId,
Expand All @@ -590,7 +606,13 @@ export class ChatSagas {

// send CU or /INSPECT open (DL Speech will do this automatically)
if (!isDLSpeechBot) {
res = yield call([ChatSagas, ChatSagas.sendInitialActivity], { conversationId, members, mode: chat.mode });
res = yield call([ChatSagas, ChatSagas.sendInitialActivities], {
conversationId,
members,
mode: chat.mode,
randomSeed: chat.randomSeed,
randomValue: chat.randomValue,
});
if (!res.ok) {
yield* throwErrorFromResponse('Error occurred while sending the initial activity', res);
}
Expand Down Expand Up @@ -644,8 +666,28 @@ export class ChatSagas {
}
}

public static *sendInitialActivity(payload: any): Iterator<any> {
const { conversationId, members, mode } = payload;
public static *sendInitialActivities(payload: InitialActivitiesPayload): Iterator<any> {
const { conversationId, members, mode, randomSeed, randomValue } = payload;
const serverUrl = yield select(getServerUrl);

// if we have a randomSeed and / or randomValue set via the UI, we need to send
// a custom event to the bot containing these values to support transcript testing
if (randomSeed !== undefined || randomValue !== undefined) {
const testOptionsActivity = {
type: 'event',
name: 'SetTestOptions',
value: {
randomSeed,
randomValue,
},
};
yield call(
[ConversationService, ConversationService.sendActivityToBot],
serverUrl,
conversationId,
testOptionsActivity
);
}

let activity;
if (mode === 'debug') {
Expand All @@ -660,7 +702,6 @@ export class ChatSagas {
membersRemoved: [],
};
}
const serverUrl = yield select(getServerUrl);
return yield call(
[ConversationService, ConversationService.sendActivityToBot],
serverUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export interface OpenBotDialogState {
appId?: string;
appPassword?: string;
isAzureGov?: boolean;
randomSeed?: number;
randomValue?: number;
speechKey?: string;
speechRegion?: string;
}
Expand Down Expand Up @@ -125,7 +127,18 @@ export class OpenBotDialog extends Component<OpenBotDialogProps, OpenBotDialogSt

public render(): ReactNode {
const { savedBotUrls = [] } = this.props;
const { botUrl, appId, appPassword, mode, isDebug, isAzureGov, speechKey, speechRegion } = this.state;
const {
botUrl,
appId,
appPassword,
mode,
isDebug,
isAzureGov,
randomSeed,
randomValue,
speechKey,
speechRegion,
} = this.state;
const validationResult = OpenBotDialog.validateEndpoint(botUrl);
const errorMessage = OpenBotDialog.getErrorMessage(validationResult);
const shouldBeDisabled =
Expand Down Expand Up @@ -186,6 +199,26 @@ export class OpenBotDialog extends Component<OpenBotDialogProps, OpenBotDialogSt
/>
</Row>
)}
<Row className={openBotStyles.multiInputRow}>
<TextField
inputContainerClassName={openBotStyles.inputContainerRow}
name="randomSeed"
label="Test Options - Random Seed"
onChange={this.onInputChange}
placeholder="Optional"
type="number"
value={randomSeed}
/>
<TextField
inputContainerClassName={openBotStyles.inputContainerRow}
label="Test Options - Random Value"
name="randomValue"
onChange={this.onInputChange}
placeholder="Optional"
type="number"
value={randomValue}
/>
</Row>
<Row className={openBotStyles.rowOverride}>
<Checkbox
label="Open in debug mode"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const mapDispatchToProps = (dispatch: (action: Action) => void): OpenBotDialogPr
botUrl = '',
mode = 'livechat-url',
isAzureGov,
randomSeed,
randomValue,
speechKey = '',
speechRegion = '',
} = componentState;
Expand All @@ -64,6 +66,8 @@ const mapDispatchToProps = (dispatch: (action: Action) => void): OpenBotDialogPr
endpoint: botUrl,
mode,
channelService: isAzureGov ? 'azureusgovernment' : 'public',
randomSeed: Number(randomSeed) || undefined,
randomValue: Number(randomValue) || undefined,
speechKey,
speechRegion,
})
Expand Down
2 changes: 2 additions & 0 deletions packages/app/shared/src/state/reducers/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export interface ChatDocument<I = any> extends Document {
inspectorObjects: I[];
log: ChatLog;
pendingSpeechTokenRetrieval: boolean;
randomSeed: number;
randomValue: number;
speechKey: string;
speechRegion: string;
ui: DocumentUI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export interface StartConversationParams extends ConversationParameters {
mode?: EmulatorMode;
channelService?: ChannelService;
conversationId?: string;
randomSeed?: number;
randomValue?: number;
speechKey?: string;
speechRegion?: string;
}

0 comments on commit 1a9973e

Please sign in to comment.