Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tests/e2e/config/wdio.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ export const config: Options.Testrunner = {

/** After test: capture screenshot on failure. */
afterTest: async function (test, context, { error, passed }) {
if (!passed) {
const isRealFailure = !passed && !!error;
if (isRealFailure) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const screenshotName = `failure-${test.title.replace(/\s+/g, '_')}-${timestamp}.png`;

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/config/wdio.conf_l0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ export const config: Options.Testrunner = {

/** After test: capture screenshot on failure. */
afterTest: async function (test, context, { error, passed }) {
if (!passed) {
const isRealFailure = !passed && !!error;
if (isRealFailure) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const screenshotName = `failure-${test.title.replace(/\s+/g, '_')}-${timestamp}.png`;

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/config/wdio.conf_l1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ export const config: Options.Testrunner = {

/** After test: capture screenshot on failure. */
afterTest: async function (test, context, { error, passed }) {
if (!passed) {
const isRealFailure = !passed && !!error;
if (isRealFailure) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const screenshotName = `failure-${test.title.replace(/\s+/g, '_')}-${timestamp}.png`;

Expand Down
8 changes: 8 additions & 0 deletions tests/e2e/specs/l0-open-settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { browser, expect, $ } from '@wdio/globals';
import { openWorkspace } from '../helpers/workspace-helper';
import { saveStepScreenshot } from '../helpers/screenshot-utils';

describe('L0 Settings Panel', () => {
let hasWorkspace = false;
Expand All @@ -25,6 +26,9 @@ describe('L0 Settings Panel', () => {

console.log('[L0] Workspace opened:', hasWorkspace);
expect(hasWorkspace).toBe(true);
if (hasWorkspace) {
await saveStepScreenshot('l0-settings-workspace-ready');
}
});
});

Expand All @@ -44,6 +48,7 @@ describe('L0 Settings Panel', () => {
// Click to open menu
await moreBtn.click();
await browser.pause(500);
await saveStepScreenshot('l0-settings-menu-opened');

// Find settings menu item
const menuItems = await $$('.bitfun-nav-panel__footer-menu-item');
Expand Down Expand Up @@ -104,6 +109,9 @@ describe('L0 Settings Panel', () => {

console.log('[L0] Settings scene opened:', sceneExists);
expect(sceneExists).toBe(true);
if (sceneExists) {
await saveStepScreenshot('l0-settings-panel-opened');
}
});
});

Expand Down
6 changes: 6 additions & 0 deletions tests/e2e/specs/l0-open-workspace.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { browser, expect, $ } from '@wdio/globals';
import { openWorkspace } from '../helpers/workspace-helper';
import { saveStepScreenshot } from '../helpers/screenshot-utils';

describe('L0 Workspace Opening', () => {
let hasWorkspace = false;
Expand All @@ -16,6 +17,7 @@ describe('L0 Workspace Opening', () => {
const title = await browser.getTitle();
console.log('[L0] App title:', title);
expect(title).toBeDefined();
await saveStepScreenshot('l0-workspace-app-started');
});

it('should have valid DOM structure', async () => {
Expand All @@ -34,6 +36,9 @@ describe('L0 Workspace Opening', () => {

console.log('[L0] Workspace opened:', hasWorkspace);
expect(hasWorkspace).toBe(true);
if (hasWorkspace) {
await saveStepScreenshot('l0-workspace-opened');
}
});

it('should have workspace UI elements', async () => {
Expand All @@ -44,6 +49,7 @@ describe('L0 Workspace Opening', () => {

console.log('[L0] Chat input exists:', hasChatInput);
expect(hasChatInput).toBe(true);
await saveStepScreenshot('l0-workspace-chat-ready');
});
});

Expand Down
10 changes: 9 additions & 1 deletion tests/e2e/specs/l1-chat-input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ChatPage } from '../page-objects/ChatPage';
import { ChatInput } from '../page-objects/components/ChatInput';
import { Header } from '../page-objects/components/Header';
import { StartupPage } from '../page-objects/StartupPage';
import { saveScreenshot, saveFailureScreenshot } from '../helpers/screenshot-utils';
import { saveScreenshot, saveFailureScreenshot, saveStepScreenshot } from '../helpers/screenshot-utils';

describe('L1 Chat Input Validation', () => {
let chatPage: ChatPage;
Expand Down Expand Up @@ -57,6 +57,10 @@ describe('L1 Chat Input Validation', () => {
console.log('[L1] Recent workspace opened successfully');
}
}

if (hasWorkspace) {
await saveStepScreenshot('l1-chat-input-workspace-ready');
}
});

describe('Input visibility and accessibility', () => {
Expand All @@ -82,6 +86,7 @@ describe('L1 Chat Input Validation', () => {
const isVisible = await chatInput.isVisible();
expect(isVisible).toBe(true);
console.log('[L1] Chat input component loaded');
await saveStepScreenshot('l1-chat-input-visible');
});

it('should have placeholder text', async function () {
Expand Down Expand Up @@ -132,6 +137,7 @@ describe('L1 Chat Input Validation', () => {
expect(value).toContain('Line 2');
expect(value).toContain('Line 3');
console.log('[L1] Multiline input works');
await saveStepScreenshot('l1-chat-input-multiline');
});

it('should clear input', async function () {
Expand Down Expand Up @@ -240,6 +246,7 @@ describe('L1 Chat Input Validation', () => {
const valueAfter = await chatInput.getValue();
expect(valueAfter).toBe('');
console.log('[L1] Input cleared after send');
await saveStepScreenshot('l1-chat-input-message-sent');
});

it('should not send empty message', async function () {
Expand Down Expand Up @@ -311,6 +318,7 @@ describe('L1 Chat Input Validation', () => {
// Main test: input is still functional
expect(typeof clearedValue).toBe('string');
console.log('[L1] Rapid sending handled - input still functional');
await saveStepScreenshot('l1-chat-input-rapid-send-complete');
});
});

Expand Down
7 changes: 6 additions & 1 deletion tests/e2e/specs/l1-editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { browser, expect, $ } from '@wdio/globals';
import { Header } from '../page-objects/components/Header';
import { StartupPage } from '../page-objects/StartupPage';
import { saveScreenshot, saveFailureScreenshot } from '../helpers/screenshot-utils';
import { saveScreenshot, saveFailureScreenshot, saveStepScreenshot } from '../helpers/screenshot-utils';
import { ensureWorkspaceOpen } from '../helpers/workspace-utils';

describe('L1 Editor', () => {
Expand All @@ -28,6 +28,8 @@ describe('L1 Editor', () => {

if (!hasWorkspace) {
console.log('[L1] No workspace available - tests will be skipped');
} else {
await saveStepScreenshot('l1-editor-workspace-ready');
}
});

Expand Down Expand Up @@ -56,6 +58,7 @@ describe('L1 Editor', () => {
if (exists) {
console.log(`[L1] Editor found: ${selector}`);
editorFound = true;
await saveStepScreenshot('l1-editor-visible');
break;
}
}
Expand Down Expand Up @@ -215,12 +218,14 @@ describe('L1 Editor', () => {
await browser.pause(300);

console.log('[L1] Switched to second tab');
await saveStepScreenshot('l1-editor-second-tab');

// Click first tab
await tabs[0].click();
await browser.pause(300);

console.log('[L1] Switched back to first tab');
await saveStepScreenshot('l1-editor-first-tab');
expect(tabs.length).toBeGreaterThanOrEqual(2);
});

Expand Down
9 changes: 8 additions & 1 deletion tests/e2e/specs/l1-file-tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { browser, expect, $ } from '@wdio/globals';
import { Header } from '../page-objects/components/Header';
import { StartupPage } from '../page-objects/StartupPage';
import { saveScreenshot, saveFailureScreenshot } from '../helpers/screenshot-utils';
import { saveScreenshot, saveFailureScreenshot, saveStepScreenshot } from '../helpers/screenshot-utils';

describe('L1 File Tree', () => {
let header: Header;
Expand Down Expand Up @@ -50,6 +50,10 @@ describe('L1 File Tree', () => {
hasWorkspace = true;
console.log('[L1] Recent workspace opened successfully');
}

if (hasWorkspace) {
await saveStepScreenshot('l1-file-tree-workspace-ready');
}
}

// Navigate to file tree view
Expand Down Expand Up @@ -80,6 +84,7 @@ describe('L1 File Tree', () => {
await navItem.click();
await browser.pause(1500); // Wait for view to switch
console.log('[L1] Navigated to Files view');
await saveStepScreenshot('l1-file-tree-files-view');
navigated = true;
break;
} catch (clickError) {
Expand Down Expand Up @@ -289,6 +294,7 @@ describe('L1 File Tree', () => {
// Verify the expand state actually changed
expect(afterExpanded).not.toBe(beforeExpanded);
console.log('[L1] Directory expand/collapse state changed successfully');
await saveStepScreenshot('l1-file-tree-directory-toggled');
break;
}
}
Expand Down Expand Up @@ -323,6 +329,7 @@ describe('L1 File Tree', () => {

const isSelected = await content.getAttribute('class');
console.log('[L1] File selected, classes:', isSelected?.includes('selected'));
await saveStepScreenshot('l1-file-tree-file-selected');
}

expect(filePath).toBeDefined();
Expand Down
67 changes: 58 additions & 9 deletions tests/e2e/specs/l1-navigation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@ import { StartupPage } from '../page-objects/StartupPage';
import { saveScreenshot, saveFailureScreenshot } from '../helpers/screenshot-utils';
import { ensureWorkspaceOpen } from '../helpers/workspace-utils';

const NAV_ENTRY_SELECTORS = [
'.bitfun-nav-panel__item',
'.bitfun-nav-panel__item-slot',
'.bitfun-nav-panel__workspace-item-name-btn',
'.bitfun-nav-panel__inline-item',
'.bitfun-nav-panel__workspace-create-main',
'.bitfun-nav-panel__toolbox-entry',
];

async function getNavigationEntryCounts(): Promise<Record<string, number>> {
const counts: Record<string, number> = {};

for (const selector of NAV_ENTRY_SELECTORS) {
counts[selector] = (await browser.$$(selector)).length;
}

return counts;
}

async function getNavigationEntries() {
const entries = [];

for (const selector of NAV_ENTRY_SELECTORS) {
const matched = await browser.$$(selector);
entries.push(...matched);
}

return entries;
}

describe('L1 Navigation', () => {
let header: Header;
let startupPage: StartupPage;
Expand Down Expand Up @@ -51,9 +81,11 @@ describe('L1 Navigation', () => {
return;
}

const navItems = await browser.$$('.bitfun-nav-panel__item');
console.log('[L1] Navigation items count:', navItems.length);
expect(navItems.length).toBeGreaterThan(0);
const counts = await getNavigationEntryCounts();
const totalEntries = Object.values(counts).reduce((sum, count) => sum + count, 0);

console.log('[L1] Navigation entry counts:', counts);
expect(totalEntries).toBeGreaterThan(0);
});

it('should have navigation sections', async function () {
Expand All @@ -75,15 +107,32 @@ describe('L1 Navigation', () => {
return;
}

const navItems = await browser.$$('.bitfun-nav-panel__item');
const navItems = await getNavigationEntries();
if (navItems.length === 0) {
console.log('[L1] No nav items to click');
this.skip();
return;
}

const firstItem = navItems[0];
const isClickable = await firstItem.isClickable();
let firstClickable = null;
for (const item of navItems) {
try {
if (await item.isClickable()) {
firstClickable = item;
break;
}
} catch (error) {
// Try the next candidate.
}
}

if (!firstClickable) {
console.log('[L1] Navigation entries exist but none are clickable');
this.skip();
return;
}

const isClickable = await firstClickable.isClickable();
expect(isClickable).toBe(true);
console.log('[L1] First navigation item is clickable');
});
Expand Down Expand Up @@ -121,7 +170,7 @@ describe('L1 Navigation', () => {
return;
}

const activeItems = await browser.$$('.bitfun-nav-panel__item.is-active');
const activeItems = await browser.$$('.bitfun-nav-panel__item.is-active, .bitfun-nav-panel__inline-item.is-active, .bitfun-nav-panel__toolbox-entry.is-active');
const activeCount = activeItems.length;
console.log('[L1] Active navigation items:', activeCount);

Expand All @@ -142,7 +191,7 @@ describe('L1 Navigation', () => {
}

// Get initial active item
const initialActive = await browser.$$('.bitfun-nav-panel__item.is-active');
const initialActive = await browser.$$('.bitfun-nav-panel__item.is-active, .bitfun-nav-panel__inline-item.is-active, .bitfun-nav-panel__toolbox-entry.is-active');
const initialActiveCount = initialActive.length;
console.log('[L1] Initial active items:', initialActiveCount);

Expand Down Expand Up @@ -180,7 +229,7 @@ describe('L1 Navigation', () => {
}

// Check for active state (don't fail if state doesn't change)
const afterActive = await browser.$$('.bitfun-nav-panel__item.is-active');
const afterActive = await browser.$$('.bitfun-nav-panel__item.is-active, .bitfun-nav-panel__inline-item.is-active, .bitfun-nav-panel__toolbox-entry.is-active');
console.log('[L1] Active items after click:', afterActive.length);

// Verify active state detection completed
Expand Down