Fix e2e tests by removing installed running quotes before running (#2407)

This commit is contained in:
Zane
2025-05-01 09:31:47 -07:00
committed by GitHub
parent 1e3c40a0ed
commit 37ed707dd6
5 changed files with 114 additions and 61 deletions

View File

@@ -24,6 +24,7 @@
"test-e2e:ui": "npm run generate-api && playwright test --ui",
"test-e2e:debug": "npm run generate-api && playwright test --debug",
"test-e2e:report": "playwright show-report",
"test-e2e:single": "npm run generate-api && playwright test -g",
"lint": "eslint \"src/**/*.{ts,tsx}\" --fix --no-warn-ignored",
"lint:check": "eslint \"src/**/*.{ts,tsx}\" --max-warnings 0 --no-warn-ignored",
"format": "prettier --write \"src/**/*.{ts,tsx,css,json}\"",

View File

@@ -63,7 +63,6 @@ export default function ChatView({
setView: (view: View, viewOptions?: ViewOptions) => void;
setIsGoosehintsModalOpen: (isOpen: boolean) => void;
}) {
return (
<ContextManagerProvider>
<ChatContent

View File

@@ -13,6 +13,7 @@ interface MenuButtonProps {
className?: string;
danger?: boolean;
icon?: React.ReactNode;
testId?: string;
}
const MenuButton: React.FC<MenuButtonProps> = ({
@@ -22,9 +23,11 @@ const MenuButton: React.FC<MenuButtonProps> = ({
className = '',
danger = false,
icon,
testId = '',
}) => (
<button
onClick={onClick}
data-testid={testId}
className={`w-full text-left px-4 py-3 min-h-[64px] text-sm hover:bg-bgSubtle transition-[background] border-b border-borderSubtle ${
danger ? 'text-red-400' : ''
} ${className}`}
@@ -259,6 +262,7 @@ export default function MoreMenu({
}}
subtitle="View all settings and options"
icon={<Sliders className="w-4 h-4 rotate-90" />}
testId="advanced-settings-button"
>
Advanced settings
<span className="text-textSubtle ml-1">,</span>

View File

@@ -99,8 +99,14 @@ async function selectProvider(mainWindow: any, provider: Provider) {
// Find and verify the provider card container
console.log(`Looking for ${provider.name} card...`);
const providerContainer = await mainWindow.waitForSelector(`[data-testid="provider-card-${provider.name.toLowerCase()}"]`);
expect(await providerContainer.isVisible()).toBe(true);
let providerContainer;
try {
providerContainer = await mainWindow.waitForSelector(`[data-testid="provider-card-${provider.name.toLowerCase()}"]`);
expect(await providerContainer.isVisible()).toBe(true);
} catch (error) {
console.error(`Provider card not found for ${provider.name}. This could indicate a missing or incorrectly configured provider.`);
throw error;
}
// Find the Launch button within the provider container
console.log(`Looking for Launch button in ${provider.name} card...`);
@@ -162,7 +168,7 @@ test.describe('Goose App', () => {
env: {
...process.env,
ELECTRON_IS_DEV: '1',
NODE_ENV: 'development'
NODE_ENV: 'development',
},
recordVideo: {
dir: 'test-results/videos/',
@@ -405,21 +411,6 @@ test.describe('Goose App', () => {
fs.mkdirSync('test-results', { recursive: true });
}
// Clean up any existing running-quotes extensions from localStorage
// todo: extensions are no longer in localstorage so we need a way to delete extensions from the ui or config to actually clean these up
await mainWindow.evaluate(() => {
const USER_SETTINGS_KEY = 'user_settings';
const settings = JSON.parse(localStorage.getItem(USER_SETTINGS_KEY) || '{"extensions":[]}');
// Remove any running-quotes extensions
settings.extensions = settings.extensions.filter(ext => ext.id !== 'running-quotes');
// Save back to localStorage
localStorage.setItem(USER_SETTINGS_KEY, JSON.stringify(settings));
console.log('Cleaned up existing running-quotes extensions');
});
try {
// Reload the page to ensure settings are fresh
await mainWindow.reload();
@@ -435,67 +426,122 @@ test.describe('Goose App', () => {
// Take screenshot of initial state
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-initial-state.png` });
// First navigate to Advanced Settings to check for existing Running Quotes extension
console.log('Checking for existing Running Quotes extension...');
// Click the menu button (3 dots)
console.log('Attempting to find menu button...');
const menuButton = await mainWindow.waitForSelector('[data-testid="more-options-button"]', {
timeout: 2000,
state: 'visible'
});
// Verify menu button is visible and clickable
const isMenuButtonVisible = await menuButton.isVisible();
console.log('Menu button visible:', isMenuButtonVisible);
// Take screenshot before clicking menu
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-before-menu.png` });
await menuButton.click();
console.log('Clicked menu button');
// Wait for menu to appear
await mainWindow.waitForTimeout(1000);
// Click Advanced settings
const advancedSettingsButton = await mainWindow.waitForSelector('button:has-text("Advanced settings")', {
timeout: 2000,
state: 'visible'
});
await advancedSettingsButton.click();
// Wait for settings page to load
await mainWindow.waitForTimeout(1000);
// Look for Running Quotes extension card
console.log('Looking for existing Running Quotes extension...');
const existingExtension = await mainWindow.$('div.flex:has-text("Running Quotes")');
if (existingExtension) {
console.log('Found existing Running Quotes extension, removing it...');
// Find and click the settings gear icon next to Running Quotes
const settingsButton = await existingExtension.$('button[aria-label="Extension settings"]');
if (settingsButton) {
await settingsButton.click();
// Wait for modal to appear
await mainWindow.waitForTimeout(500);
// Click the Remove Extension button
const removeButton = await mainWindow.waitForSelector('button:has-text("Remove Extension")', {
timeout: 2000,
state: 'visible'
});
await removeButton.click();
// Wait for confirmation modal
await mainWindow.waitForTimeout(500);
// Click the Remove button in confirmation dialog
const confirmButton = await mainWindow.waitForSelector('button:has-text("Remove")', {
timeout: 2000,
state: 'visible'
});
await confirmButton.click();
// Wait for extension to be removed
await mainWindow.waitForTimeout(1000);
}
}
// Click Back to return to main menu
let backButton = await mainWindow.waitForSelector('button:has-text("Back")', {
timeout: 2000,
state: 'visible'
});
await backButton.click();
// Wait for menu transition
await mainWindow.waitForTimeout(1000);
// Now proceed with adding the extension
console.log('Proceeding with adding Running Quotes extension...');
// Find and click the menu button (3 dots) again
console.log('Finding menu button again...');
const menuButtonAgain = await mainWindow.waitForSelector('[data-testid="more-options-button"]', {
timeout: 2000,
state: 'visible'
});
await menuButtonAgain.click();
// Wait for menu to appear and take screenshot
await mainWindow.waitForTimeout(1000);
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-after-menu.png` });
// Click Advanced settings
console.log('Looking for Advanced settings button...');
const advancedSettingsButton = await mainWindow.waitForSelector('button:has-text("Advanced settings")', {
// Click Advanced settings again
console.log('Looking for Advanced settings button again...');
const advancedSettingsButtonAgain = await mainWindow.waitForSelector('button:has-text("Advanced settings")', {
timeout: 2000,
state: 'visible'
});
// Verify advanced settings button is visible
const isAdvancedSettingsVisible = await advancedSettingsButton.isVisible();
console.log('Advanced settings button visible:', isAdvancedSettingsVisible);
await advancedSettingsButton.click();
await advancedSettingsButtonAgain.click();
console.log('Clicked Advanced settings');
// Wait for navigation and take screenshot
await mainWindow.waitForTimeout(1000);
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-settings-page.png` });
// Click Add Custom Extension button
console.log('Looking for Add Custom Extension button...');
const addExtensionButton = await mainWindow.waitForSelector('button:has-text("Add Custom Extension")', {
// Click "Add custom extension" button
console.log('Looking for Add custom extension button...');
const addExtensionButton = await mainWindow.waitForSelector('button:has-text("Add custom extension")', {
timeout: 2000,
state: 'visible'
});
// Verify add extension button is visible
const isAddExtensionVisible = await addExtensionButton.isVisible();
console.log('Add Extension button visible:', isAddExtensionVisible);
console.log('Add custom extension button visible:', isAddExtensionVisible);
await addExtensionButton.click();
console.log('Clicked Add Custom Extension');
console.log('Clicked Add custom extension');
// Wait for modal and take screenshot
await mainWindow.waitForTimeout(1000);
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-modal.png` });
// Get page content for debugging
const modalContent = await mainWindow.evaluate(() => document.body.innerHTML);
console.log('Modal content:', modalContent);
// Fill the form
console.log('Filling form fields...');
@@ -515,7 +561,7 @@ test.describe('Goose App', () => {
// Fill Command
const mcpScriptPath = join(__dirname, 'basic-mcp.ts');
const commandInput = await mainWindow.waitForSelector('input[placeholder*="npx -y @modelcontextprotocol"]', {
const commandInput = await mainWindow.waitForSelector('input[placeholder="e.g. npx -y @modelcontextprotocol/my-extension <filepath>"]', {
timeout: 2000,
state: 'visible'
});
@@ -524,18 +570,23 @@ test.describe('Goose App', () => {
// Take screenshot of filled form
await mainWindow.screenshot({ path: `test-results/${provider.name.toLowerCase()}-filled-form.png` });
// Click Add Extension button
console.log('Looking for Add Extension button...');
const addButton = await mainWindow.waitForSelector('button:has-text("Add Extension")', {
// Wait for any animations to complete
await mainWindow.waitForTimeout(1000);
// Click Add Extension button in modal footer
console.log('Looking for Add Extension button in modal...');
const modalAddButton = await mainWindow.waitForSelector('button.text-textProminent', {
timeout: 2000,
state: 'visible'
});
// Verify add button is visible
const isAddButtonVisible = await addButton.isVisible();
console.log('Add button visible:', isAddButtonVisible);
// Verify button is visible
const isModalAddButtonVisible = await modalAddButton.isVisible();
console.log('Add Extension button visible:', isModalAddButtonVisible);
// Click the button
await modalAddButton.click();
await addButton.click();
console.log('Clicked Add Extension button');
// Wait for the Running Quotes extension to appear in the list
@@ -563,10 +614,6 @@ test.describe('Goose App', () => {
} catch (error) {
console.error('Error verifying extension:', error);
// Get current page content
const pageContent = await mainWindow.evaluate(() => document.body.innerHTML);
console.log('Page content after clicking Add Extension:', pageContent);
// Get any error messages that might be visible
const errorElements = await mainWindow.$$eval('.text-red-500, .text-error',
elements => elements.map(el => el.textContent)
@@ -579,7 +626,7 @@ test.describe('Goose App', () => {
}
// Click Back button
const backButton = await mainWindow.waitForSelector('button:has-text("Back")', {
backButton = await mainWindow.waitForSelector('button:has-text("Back")', {
timeout: 2000,
state: 'visible'
});

View File

@@ -20,11 +20,13 @@ async function showTestName(mainWindow: any, testName: string, providerName?: st
font-family: monospace;
font-size: 14px;
z-index: 2147483647; // maximum z-index integer value
pointer-events: none;
pointer-events: none !important;
text-align: center;
max-width: 80%;
white-space: pre-wrap;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
user-select: none;
-webkit-user-select: none;
`;
const testText = `Running: ${name}`;