Productivity App Testing Guide

How to Test Notion Onboarding: Workspace Setup, Templates & Block Editor

A scenario-by-scenario walkthrough of testing Notion workspace onboarding with Playwright. Template gallery selection, keyboard-driven block editor interactions, drag-and-drop page organization, workspace settings, member invitations, and the pitfalls that break real onboarding test suites.

100M+

Notion surpassed 100 million users in 2024, with workspace onboarding being the first experience every team encounters before adopting the platform.

Notion (2024 company announcement)

0Onboarding steps covered
0Scenarios tested
0+Keyboard shortcuts in editor
0%Fewer lines with Assrt

Notion Workspace Onboarding Flow

BrowserNotion AppAuth ServiceAPI ServerTemplate EngineVisit notion.so/signupCreate account / OAuthSession tokenRender workspace setup wizardSubmit workspace name & use caseProvision workspace + templatesTemplate pages createdRedirect to workspace home

1. Why Testing Notion Workspace Onboarding Is Harder Than It Looks

Notion workspace onboarding looks straightforward on the surface: sign up, name your workspace, pick a use case, choose some templates, and start editing. But under the hood, the experience is built on a rich client-side application that makes heavy use of keyboard shortcuts, contentEditable regions, drag-and-drop interactions, and dynamically rendered block trees. Every one of those patterns is notoriously difficult to automate with Playwright.

The template gallery is the first challenge. When a new user selects a use case (engineering, design, marketing, personal), Notion presents a curated set of templates with live previews. These templates are not static HTML pages. They are rendered as interactive block trees that load asynchronously, with skeleton placeholders that transition to real content. Your test needs to wait for the template preview to fully render before asserting on its contents, and the timing varies significantly based on template complexity.

The block editor is the second major obstacle. Notion's editor is built on contentEditable elements with a custom input handling layer that intercepts keyboard events. Standard Playwright fill() calls do not work reliably because Notion captures keydown events and routes them through its own command system. You need page.keyboard.type() and page.keyboard.press() to simulate real keystrokes. Slash commands (typing/ to open the block menu) require precise timing between the slash keystroke and the subsequent selection.

Drag-and-drop page organization is the third pain point. The sidebar allows users to reorder pages, nest them inside other pages, and move them between sections. Playwright's native drag API works inconsistently with Notion's custom drag handlers because Notion uses a virtual drag layer with its own hit detection. You often need to simulate the full mouse event sequence (mousedown, multiple mousemove events, mouseup) with precise coordinates.

Finally, workspace settings involve modals, permission dropdowns, email invitation forms, and plan selection screens that load asynchronously. Each modal has its own focus trap, and clicking outside dismisses it, which means stray mouse events in your test can close a settings panel before your assertions run.

Notion Onboarding Step Sequence

🌐

Sign Up

Email or Google OAuth

⚙️

Workspace Name

Name and icon

Use Case

Team type selection

🌐

Template Gallery

Pick starter templates

📧

Invite Members

Email invitations

Workspace Home

Landing page with templates

Block Editor Input Pipeline

🌐

Keystroke

User presses key

⚙️

Event Capture

Notion intercepts keydown

↪️

Command Router

Slash, markdown, or text

⚙️

Block Update

Virtual DOM patch

Render

contentEditable reflects change

A thorough Notion onboarding test suite must handle all of these surfaces. The sections below walk through each scenario with runnable Playwright TypeScript you can paste into a real project.

2. Setting Up a Reliable Test Environment

Notion does not offer a public API for creating or deleting workspaces programmatically, so your test environment setup requires a different strategy than API-first products like Auth0 or Stripe. You need a dedicated test account, a clean workspace for each test run, and a way to reset state between runs.

Notion Test Environment Checklist

  • Create a dedicated Notion account using a test email (e.g., test+notion@yourcompany.com)
  • Use a fresh workspace for each test suite run (delete via settings after each run)
  • Store session cookies using Playwright storageState to avoid re-authentication
  • Configure Playwright for a 30-second navigation timeout (template loading is slow)
  • Set viewport to 1280x800 minimum (Notion sidebar collapses on narrow viewports)
  • Disable Notion's onboarding tooltips using localStorage flags when possible
  • Use a stable network connection (Notion's real-time sync is sensitive to latency)
  • Pin the Playwright browser version to avoid rendering differences across updates

Environment Variables

.env.test

Playwright Configuration

Notion is a heavy client-side application with aggressive lazy loading. Your Playwright config needs generous timeouts, a fixed viewport size, and permission for clipboard access (Notion uses clipboard heavily for copy-paste between blocks).

playwright.config.ts

Authentication Helper

Since Notion does not expose a headless authentication API, your global setup must log in through the browser and save the session. Use Playwright's storageState to persist cookies across test projects.

test/global-setup.ts
Install Dependencies

3. Scenario: Workspace Creation Wizard

The workspace creation wizard is the first thing a new Notion user sees after signing up. It collects a workspace name, an optional icon, a use case selection (team engineering, design, product, personal), and the team size. Each step transitions with an animation, and the wizard does not expose traditional form inputs. Instead, it uses clickable cards for use case selection and a contentEditable field for the workspace name.

1

Complete Workspace Creation Wizard

Moderate

Goal

Navigate through the full workspace creation wizard, set a workspace name, select a use case, and arrive at the workspace home page with the correct workspace name displayed.

Preconditions

  • Authenticated Notion account with no existing workspaces
  • Browser viewport at least 1280x800

Playwright Implementation

test/onboarding/workspace-creation.spec.ts

Assrt Equivalent

# scenarios/notion-workspace-creation.assrt
describe: Complete workspace creation wizard

given:
  - I am logged in to a Notion account with no workspaces
  - I am on the onboarding page

steps:
  - type "QA Test Workspace" into the workspace name field
  - click "Continue"
  - select the "Engineering" use case card
  - click "Continue"
  - select "Just me" for team size
  - click "Continue"

expect:
  - the sidebar is visible within 30 seconds
  - the sidebar shows "QA Test Workspace"
  - at least one default page exists in the sidebar

Workspace Creation: Playwright vs Assrt

import { test, expect } from '@playwright/test';

test('workspace creation wizard', async ({ page }) => {
  await page.goto('https://www.notion.so/onboarding');

  const nameInput = page.locator('[data-testid="workspace-name-input"]');
  await nameInput.click();
  await page.keyboard.type('QA Test Workspace');
  await page.getByRole('button', { name: /continue/i }).click();

  await page.waitForSelector('[data-testid="usecase-card"]');
  const card = page.locator(
    '[data-testid="usecase-card"]:has-text("Engineering")'
  );
  await card.click();
  await page.getByRole('button', { name: /continue/i }).click();

  await page.locator(
    '[data-testid="team-size-option"]:has-text("Just me")'
  ).click();
  await page.getByRole('button', { name: /continue/i }).click();

  await page.waitForSelector('[data-testid="sidebar"]', {
    timeout: 30_000,
  });
  const name = page.locator(
    '[data-testid="sidebar-workspace-switcher"]'
  );
  await expect(name).toContainText('QA Test Workspace');
});
50% fewer lines

Try Assrt for free

Open-source AI testing framework. No signup required.

Get Started

5. Scenario: Block Editor Keyboard Interactions

Notion's block editor is the core of the product, and testing it requires understanding how Notion handles keyboard input. Unlike a standard textarea or input field, Notion's editor uses contentEditable divs with a custom event handler layer. Calling locator.fill() will not work because Notion intercepts and re-routes keydown events through its own command pipeline. You must use page.keyboard.type() for text input and page.keyboard.press() for shortcuts and special keys.

Slash commands are Notion's power feature. Typing/ opens a searchable command menu that lets users create headings, toggle lists, callout blocks, code blocks, databases, and more. Testing slash commands requires typing the slash, waiting for the menu to appear, typing a filter query, and then pressing Enter or clicking the correct menu item. The menu is a floating overlay positioned relative to the cursor, and it updates its contents as you type.

3

Block Editor: Text Input and Slash Commands

Complex

Goal

Create a new page, type text into the block editor using keyboard simulation, use slash commands to create different block types, and verify the resulting block structure.

Preconditions

  • Authenticated session with an existing workspace
  • No tooltip overlays blocking the editor area

Playwright Implementation

test/editor/block-editor-keyboard.spec.ts

Keyboard Shortcuts Reference

Notion supports over 40 keyboard shortcuts in the editor. Here are the most important ones to test during onboarding flows, along with the Playwright method to trigger each.

test/helpers/notion-keyboard-shortcuts.ts

Assrt Equivalent

# scenarios/notion-block-editor.assrt
describe: Block editor text input and slash commands

given:
  - I am logged in to my workspace
  - I create a new blank page

steps:
  - type "E2E Test Page" as the page title
  - press Enter to move to the first content block
  - type "This is an automated test paragraph."
  - press Enter
  - type "/" to open the slash command menu
  - type "heading 2" and press Enter
  - type "Test Section Heading"
  - press Enter
  - type "/" and select "to-do"
  - type "First task item" and press Enter
  - type "Second task item"

expect:
  - the page title is "E2E Test Page"
  - a heading "Test Section Heading" is visible
  - two to-do items are visible
  - at least 4 content blocks exist on the page

6. Scenario: Drag-and-Drop Page Organization

Notion's sidebar allows users to organize pages by dragging them into different positions and nesting them under other pages. This is a critical part of workspace onboarding because new users need to organize the templates and pages they have created into a coherent structure. Testing drag-and-drop in Notion is notoriously difficult because Notion uses a custom virtual drag layer that does not respond reliably to Playwright's built-in dragTo() method.

The reliable approach is to simulate the full mouse event sequence: mousedown on the source element, a series of mousemove events along the drag path, and mouseup on the target. You also need to account for Notion's drop indicators, which are thin colored lines that appear between items or indented under a parent page. The drop indicator position determines whether the page is placed before, after, or nested inside the target.

4

Sidebar Drag-and-Drop Page Nesting

Complex

Goal

Drag a page in the sidebar and nest it under another page, then verify the page hierarchy updated correctly.

Playwright Implementation

test/onboarding/drag-drop-sidebar.spec.ts

Assrt Equivalent

# scenarios/notion-drag-drop-sidebar.assrt
describe: Nest a page under another page via drag-and-drop

given:
  - I am logged in to my workspace
  - "Child Page" and "Parent Page" exist in the sidebar

steps:
  - drag "Child Page" onto "Parent Page" in the sidebar
  - wait for the page hierarchy to update

expect:
  - "Child Page" is nested under "Parent Page"
  - expanding "Parent Page" reveals "Child Page" as a sub-page

7. Scenario: Workspace Settings and Member Invitations

Workspace settings are a key part of the onboarding experience, especially for team workspaces. New workspace owners need to configure the workspace name, icon, allowed email domains, and default permissions. They also need to invite team members via email. All of this happens inside modal dialogs that load asynchronously and have their own focus management.

5

Workspace Settings and Email Invitation

Moderate

Goal

Open workspace settings, update the workspace name and icon, invite a team member via email, and verify the invitation was sent.

Playwright Implementation

test/onboarding/workspace-settings.spec.ts

Assrt Equivalent

# scenarios/notion-workspace-settings.assrt
describe: Update workspace settings and invite a member

given:
  - I am logged in as the workspace owner

steps:
  - open workspace settings from the sidebar
  - change the workspace name to "Updated Workspace Name"
  - click "Update"
  - go to the Members tab
  - invite a new member by entering their email
  - click "Invite"

expect:
  - a success message appears for the invitation
  - the invited email shows in the member list
  - the sidebar reflects "Updated Workspace Name"

8. Scenario: Mobile Responsive Onboarding

Notion's onboarding flow adapts to mobile viewports, and a significant portion of new signups happen on mobile devices. On narrow screens, the sidebar collapses into a hamburger menu, the template gallery switches to a vertical scroll layout, and the block editor adjusts its toolbar positioning. Testing the mobile experience requires a separate Playwright project with a mobile viewport and touch emulation.

6

Mobile Viewport Onboarding Flow

Moderate

Goal

Complete the workspace creation wizard on a mobile viewport, verify the sidebar is accessible via hamburger menu, and confirm template selection works with a vertical layout.

Playwright Implementation

test/onboarding/mobile-onboarding.spec.ts

Assrt Equivalent

# scenarios/notion-mobile-onboarding.assrt
describe: Mobile workspace onboarding flow
device: iPhone 14

given:
  - I am on the onboarding page on a mobile device

steps:
  - type "Mobile Test Workspace" as the workspace name
  - click "Continue"
  - select the "Personal" use case
  - click "Continue" twice

expect:
  - a hamburger menu icon is visible
  - tapping the hamburger menu reveals the sidebar
  - the sidebar shows "Mobile Test Workspace"
  - at least one default page is listed

9. Common Pitfalls That Break Notion Onboarding Tests

Using fill() Instead of keyboard.type() in the Block Editor

The most common mistake when automating Notion is using Playwright's fill()method on contentEditable elements. Notion's editor intercepts keyboard events at the document level and routes them through its own command pipeline. The fill()method sets the value programmatically, bypassing Notion's input handlers entirely. This causes the block content to appear visually but not be registered by Notion's internal state, leading to data loss on save. Always use page.keyboard.type() for any text entry in the Notion editor.

Insufficient Timeouts for Template Loading

Notion templates load asynchronously, and complex templates (like project management boards with multiple database views) can take 10 to 15 seconds to fully render. Playwright's default 5-second timeout will cause intermittent failures. Use explicit waitForSelector calls with 15-second timeouts for template content, and add an additional check that skeleton loaders have disappeared before asserting on block content.

Onboarding Tooltips and Coach Marks Blocking Interactions

Notion shows onboarding tooltips, coach marks, and feature announcement banners to new users. These overlays can intercept click events intended for buttons or editor elements. Dismiss them explicitly at the start of each test by looking for known tooltip selectors like[data-testid="tooltip-dismiss"] and clicking them. Alternatively, set localStorage flags before navigation to suppress tooltips:page.evaluate(() => localStorage.setItem('hasSeenOnboardingTooltips', 'true')).

Notion's Real-Time Sync Causing Race Conditions

Notion syncs changes in real time via WebSocket connections. If your test types text and immediately reads it back from the DOM, you may hit a race condition where Notion's sync layer has not yet committed the change. This is especially problematic with the sidebar, which updates asynchronously when new pages are created. Add a short wait or use expect().toContainText()with Playwright's auto-retry behavior instead of reading the DOM directly.

Drag-and-Drop Failing Silently

Playwright's dragTo()method dispatches a simplified drag event sequence that Notion's custom drag handler may not recognize. The drag appears to execute (no error is thrown), but the page order does not change. Always verify the result after a drag operation. If the order has not changed, fall back to the manual mouse event sequence with small incremental moves (mousedown, multiple mousemove events at 10-pixel intervals, mouseup) as shown in Section 6. The incremental moves are necessary because Notion only activates its drop target detection after the pointer moves a minimum distance from the drag origin.

Notion Test Suite Anti-Patterns

  • Using fill() on contentEditable elements in the block editor
  • Using default 5-second timeouts for template loading
  • Ignoring onboarding tooltips that block click targets
  • Reading DOM immediately after typing without waiting for sync
  • Using dragTo() for sidebar page reordering
  • Hardcoding Notion selectors that change between releases
  • Running tests without clearing workspace state between runs
  • Testing on a viewport narrower than 1280px without mobile-specific assertions
Notion Onboarding Test Suite Run
Common Error: fill() on contentEditable

10. Writing These Scenarios in Plain English with Assrt

Every scenario above requires deep knowledge of Notion's internal DOM structure: data-testid attributes that may change between releases, contentEditable quirks, custom drag handlers, and floating menu positioning. The block editor scenario alone is 50+ lines of Playwright TypeScript with precise timing for slash command menus. Multiply that by eight scenarios and you have a test suite that is fragile, hard to read, and expensive to maintain.

Assrt lets you describe what you want to test in plain English. The framework resolves selectors at runtime, adapts to DOM changes, and regenerates the underlying Playwright code when Notion updates its interface. Your scenario descriptions stay stable even when Notion renames a data-testid attribute, moves a button, or restructures its template gallery layout.

Here is the complete onboarding suite from Sections 3 through 8 compiled into a single Assrt file. Notice how the drag-and-drop scenario, which required 40+ lines of manual mouse event simulation in Playwright, becomes a single step in Assrt.

scenarios/notion-onboarding-suite.assrt

Assrt compiles each scenario block into the same Playwright TypeScript you saw in the preceding sections. The compiled tests are committed to your repo as real, runnable spec files that you can inspect, modify, and run directly with npx playwright test. When Notion updates its DOM structure, renames a button, or changes the template gallery layout, Assrt detects the failure, analyzes the new DOM, and opens a pull request with updated selectors. Your scenario descriptions stay untouched.

Start with the workspace creation wizard. Once it is green in CI, add the template gallery scenario, then the block editor with slash commands, then drag-and-drop, then workspace settings. Within an afternoon, you can have complete Notion onboarding coverage that most teams never achieve by writing raw Playwright scripts.

Related Guides

Ready to automate your testing?

Assrt discovers test scenarios, writes Playwright tests from plain English, and self-heals when your UI changes.

$npm install @assrt/sdk