Unlock a new dimension in presenting coding demos – effortlessly click through them as if they were presentation slides, thanks to this cutting-edge VSCode extension.
Features
Currently the extension supports the following features:
Multiple demo files located in .demo folder
Support for code/snippet files in the .demo folder. These files can be referenced in the demo steps, instead of adding the code in the JSON file.
Explorer panel to execute your demo steps
Add new demo steps (execute the Demo Time: Add as demo step command)
Run through the demo steps (execute the Demo Time: Start command)
Presentation mode which allows you to use a clicker to navigate through the demo steps
Supported demo steps
File actions
Action
Description
Usage
create
Create a new file
{
"action": "create",
"path": "<relative path to the file>",
"content": "<content of the file> (optional)",
"contentPath": "<relative path to the file in the .demo folder> (optional)"
}
open
Open a file
{
"action": "open",
"path": "<relative path to the file>"
}
Code actions
Action
Description
Usage
insert
Insert code into a file
{
"action": "insert",
"path": "<relative path to the file>",
"position": "<line number> or <start line number>:<end line number>",
"content": "<content of the file> (optional)",
"contentPath": "<relative path to the file in the .demo folder> (optional)"
}
replace
Replace code in a file
{
"action": "replace",
"path": "<relative path to the file>",
"position": "<line number> or <start line number>:<end line number>",
"content": "<content of the file> (optional)",
"contentPath": "<relative path to the file in the .demo folder> (optional)"
}
delete
Delete code from a file
{
"action": "delete",
"path": "<relative path to the file>",
"position": "<line number> or <start line number>:<end line number>"
}
highlight
Highlight code in a file. You can change the border color with the
demoTime.highlightBorderColor setting.
{
"action": "highlight",
"path": "<relative path to the file>",
"position": "<line number> or <start line number>:<end line number>"
}
unselect
Unselect code in a file
{
"action": "unselect",
"path": "<relative path to the file>"
}
Time actions
Action
Description
Usage
waitForTimeout
Wait for a specific amount of time
{
"action": "waitForTimeout",
"timeout": "<timeout in milliseconds>"
}
waitForInput
Wait until the user presses a key
{
"action": "waitForInput"
}
VSCode actions
Action
Description
Usage
executeVSCodeCommand
Execute a VSCode command
{
"action": "executeVSCodeCommand",
"command": "<command to execute>",
"args": "<arguments to pass to the command (optional)>"
}
{
"action": "executeTerminalCommand",
"command": "<command to execute>"
}
Snippets
Action
Description
Usage
snippet
Use a snippet in which you can define multiple reusable steps
{"action": "snippet","contentPath": "<relative path to the file in the .demo folder> (optional)""args": {// Define the argument name in the snippet file with curly braces {argument name}"<argument name>": "<argument value>"}}
Usage
To use the extension, you need to create a .demo folder in your workspace. Once created, you can add a JSON file which contains the demo and its steps.
Settings
Setting
Description
Default
demoTime.highlightBorderColor
The border color of the highlighted code
rgba(255,0,0,0.5)
demoTime.highlightZoomEnabled
Enable zooming when highlighting code
false
Tips
Position
For the position you can use the following formats:
number: The line number
number:number: The start and end line number
The start and end keywords can also be used instead of the line numbers
start will be replaced by the first line number
end will be replaced by the last line number
Adding content to a file
When you want to insert content to a file, you can use the content or contentPath properties in the demo step.
Property
Description
content
This property allows you to add the content directly in the JSON file, but this can make your JSON file quite big and it can be hard to read.
contentPath
This property allows you to reference a file in the .demo folder. This way you can keep your JSON file clean and add the content in separate files. Important: the path is relative to the .demo folder.
Example
Here is an example demo:
{
"$schema": "https://elio.dev/demo-time.schema.json",
"title": "Playwright demo",
"description": "Playwright demo for Microsoft 365",
"demos": [{
"title": "Login to Microsoft 365",
"description": "Login to Microsoft 365 using Playwright",
"steps": [{
"action": "create",
"path": "/tests/login.setup.ts",
"content": "import { test as setup } from \"@playwright/test\";\nimport { existsSync } from \"fs\";\n\nconst authFile = \"playwright/.auth/user.json\";\n\n// More info: https://playwright.dev/docs/auth\n\nsetup(\"authenticate\", async ({ page }) => {\n // Check if the auth file exists\n if (existsSync(authFile)) {\n return;\n }\n\n await page.goto(process.env.SP_DEV_PAGE_URL || \"\");\n\n page.locator(\"input[type=email]\").fill(process.env.SP_DEV_USERNAME || \"\");\n\n await page.getByRole(\"button\", { name: \"Next\" }).click();\n\n page.locator(\"input[type=password]\").fill(process.env.SP_DEV_PASSWORD || \"\");\n\n await Promise.all([\n await page.locator(\"input[type=submit][value='Sign in']\").click(),\n await page.locator(\"input[type=submit][value='Yes']\").click(),\n await page.waitForURL(process.env.SP_DEV_PAGE_URL || \"\"),\n ]);\n\n await page.context().storageState({ path: authFile });\n});"
},
{
"action": "open",
"path": "/tests/login.setup.ts"
}
]
},
{
"title": "First SharePoint tests",
"description": "Create the first SharePoint tests",
"steps": [{
"action": "create",
"path": "/tests/pages/sharepoint.spec.ts",
"content": "import { test, expect, Page } from \"@playwright/test\";\n\n// test.describe.configure({ mode: \"serial\" });\n\ntest.describe(`Validate sticker inventory`, () => {\n let page: Page;\n\n test.beforeAll(async ({ browser }) => {\n page = await browser.newPage();\n await page.goto(process.env.SP_DEV_PAGE_URL || \"\", {\n waitUntil: \"domcontentloaded\",\n });\n\n await page\n .locator(\n `div[data-sp-web-part-id=\"0e05b9af-5e56-4570-8b3e-9d679f8b2fcf\"]`\n )\n .waitFor();\n });\n\n test(`Check if webpart is rendered`, async () => {\n const webpart = page.locator(\n `div[data-sp-web-part-id=\"0e05b9af-5e56-4570-8b3e-9d679f8b2fcf\"]`\n );\n await expect(webpart).toBeVisible();\n });\n\n test.afterAll(async () => {\n await page.close();\n });\n});"
},
{
"action": "open",
"path": "/tests/pages/sharepoint.spec.ts"
},
{
"action": "highlight",
"path": "/tests/pages/sharepoint.spec.ts",
"position": "21:26"
}
]
},
{
"title": "Check the amounts",
"description": "Check the amounts of the stickers",
"steps": [{
"action": "insert",
"path": "/tests/pages/sharepoint.spec.ts",
"position": 27,
"content": "\n test(`Check if there are 7 stickers`, async () => {\n const stickers = page.getByTestId(`sticker_inventory__overview__sticker`);\n await expect(stickers).toHaveCount(7);\n });\n"
}]
}
]
}
About
A Visual Studio Code extension to help you script your demos