diff --git a/extensions/integration-tests/src/test/notebook.test.ts b/extensions/integration-tests/src/test/notebook.test.ts index faad30ad9d..2c21f6b015 100644 --- a/extensions/integration-tests/src/test/notebook.test.ts +++ b/extensions/integration-tests/src/test/notebook.test.ts @@ -55,7 +55,7 @@ suite('Notebook integration test suite', function () { assert(actualOutput2[0] === '1', `Expected result: 1, Actual: '${actualOutput2[0]}'`); }); - test.skip('Sql NB multiple cells test', async function () { + test('Sql NB multiple cells test', async function () { let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++); await runCells(notebook); const expectedOutput0 = '(1 row affected)'; @@ -84,7 +84,7 @@ suite('Notebook integration test suite', function () { } }); - test.skip('Sql NB run cells above and below test', async function () { + test('Sql NB run cells above and below test', async function () { let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++); // When running all cells above a cell, ensure that only cells preceding current cell have output await runCells(notebook, true, undefined, notebook.document.cells[1]); @@ -101,13 +101,13 @@ suite('Notebook integration test suite', function () { assert(notebook.document.cells[2].contents.outputs.length === 3, `Expected length: '3', Actual: '${notebook.document.cells[2].contents.outputs.length}'`); }); - test.skip('Clear cell output - SQL notebook', async function () { + test('Clear cell output - SQL notebook', async function () { let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++); await runCell(notebook); await verifyClearOutputs(notebook); }); - test.skip('Clear all outputs - SQL notebook', async function () { + test('Clear all outputs - SQL notebook', async function () { let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++); await runCell(notebook); await verifyClearAllOutputs(notebook); @@ -128,7 +128,7 @@ suite('Notebook integration test suite', function () { }); }); - test.skip('should not be dirty after saving notebook test', async function () { + test('should not be dirty after saving notebook test', async function () { // Given a notebook that's been edited (in this case, open notebook runs the 1st cell and adds an output) let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title); await runCell(notebook); diff --git a/src/sql/workbench/services/notebook/browser/interface.ts b/src/sql/workbench/services/notebook/browser/interface.ts index b886d1c2ef..4fd7162556 100644 --- a/src/sql/workbench/services/notebook/browser/interface.ts +++ b/src/sql/workbench/services/notebook/browser/interface.ts @@ -9,8 +9,8 @@ import { IContentManager } from 'sql/workbench/services/notebook/browser/models/ import { IStandardKernelWithProvider } from 'sql/workbench/services/notebook/browser/models/notebookUtils'; export interface INotebookInput { - defaultKernel: azdata.nb.IKernelSpec, - connectionProfile: azdata.IConnectionProfile, + defaultKernel?: azdata.nb.IKernelSpec, + connectionProfile?: azdata.IConnectionProfile, isDirty(): boolean; setDirty(boolean); readonly notebookUri: URI; @@ -22,12 +22,13 @@ export interface INotebookInput { } export function isINotebookInput(value: any): value is INotebookInput { - if (typeof value.defaultKernel === 'object' && - typeof value.connectionProfile === 'object' && - typeof value.isDirty === 'boolean' && - value.notebookUri instanceof URI && + if ( + (typeof value.defaultKernel === 'object' || value.defaultKernel === undefined) && + (typeof value.connectionProfile === 'object' || value.connectionProfile === undefined) && + typeof value.notebookUri === 'object' && + typeof value.isDirty === 'function' && + typeof value.layoutChanged === 'function' && typeof value.editorOpenedTimestamp === 'number' && - typeof value.layoutChanged === 'object' && typeof value.contentManager === 'object' && typeof value.standardKernels === 'object') { return true; diff --git a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts index 24eb6d7690..782ca5468b 100644 --- a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts +++ b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts @@ -407,8 +407,7 @@ export class NotebookService extends Disposable implements INotebookService { if (!notebookUri) { return undefined; } - // The NotebookEditor will not be found if there is query or fragments attached to the URI - let uriString = notebookUri.with({ query: '', fragment: '' }).toString(); + let uriString = getNotebookUri(notebookUri); let editor = this.listNotebookEditors().find(n => n.id === uriString); return editor; } @@ -707,3 +706,16 @@ export class NotebookService extends Disposable implements INotebookService { this._onCodeCellExecutionStart.fire(); } } + +/** + * Untitled notebookUri's need to have the query in order to get the NotebookEditor to run other actions (Run All Cells for example) on parameterized notebooks + * otherwise we strip the query and fragment from the notebookUri for all other file schemes + * @param notebookUri of the notebook + * @returns uriString that contains the formatted notebookUri + */ +export function getNotebookUri(notebookUri: URI): string { + if (notebookUri.scheme === 'untitled') { + return notebookUri.toString(); + } + return notebookUri.with({ query: '', fragment: '' }).toString(); +}