Files
bruno/tests/protobuf/manage-protofile.spec.ts
Sid 6e8cd55b76 Refactor: Change how test runner handles pageWithUserData tests (#5922)
* refactor: change how test runner opens pageWithUserData instances

* fix: test move tabs

* fix: custom ca cert tests

* fix: update file patterns and improve error messages

* fix: improve electron app launch logic

* fix: update temporary directory handling for Electron app

* fix: ensure newline at end of file in index.ts

This change adds a newline at the end of the file to comply with coding standards.

* fix: improve error handling in recursiveCopy function

- Simplified error message when source path does not exist.
- Enhanced error handling to provide clearer guidance on usage of `page` fixture.

* fix(e2e): close collections after each tests

* fix: reuse the worker instance per file instead of per user data dir

* fix: revert ssl tests as serial run is fixed

* fix: change afterEach to afterAll for cleanup

fix: change afterEach to afterAll for cleanup

---------

Co-authored-by: Bijin Bruno <bijin@usebruno.com>
2025-10-29 14:32:45 +05:30

155 lines
7.4 KiB
TypeScript

import { test, expect } from '../../playwright';
import { closeAllCollections } from '../utils/page';
test.describe('manage protofile', () => {
test.afterAll(async ({ pageWithUserData: page }) => {
await closeAllCollections(page);
});
test('protofiles, import paths from bruno.json are visible in the protobuf settings', async ({ pageWithUserData: page }) => {
await page.locator('#sidebar-collection-name').filter({ hasText: 'Grpcbin' }).click();
await page.getByRole('tab', { name: 'Protobuf' }).click();
// Wait for protobuf settings to load
const protobufProtoFilesSection = page.getByTestId('protobuf-proto-files-section');
await protobufProtoFilesSection.waitFor({ state: 'visible' });
// Check proto files table
const protoFilesTable = page.getByTestId('protobuf-proto-files-table');
await expect(protoFilesTable).toBeVisible();
const file = page.getByRole('cell', { name: 'product.proto', exact: true });
expect(file).toBeVisible();
const filePath = page.getByRole('cell', { name: '../protos/services/product.proto' });
expect(filePath).toBeVisible();
// Check import paths table
const importPathsTable = page.getByTestId('protobuf-import-paths-table');
await expect(importPathsTable).toBeVisible();
const importPath = page.getByRole('cell', { name: '../protos/types', exact: true });
await expect(importPath).toBeVisible();
const invalidFilePath = page.getByRole('cell', { name: 'invalid-file-path.proto', exact: true });
await expect(invalidFilePath).toBeVisible();
const invalidImportPath = page.getByRole('cell', { name: '../protos/invalid-import-path', exact: true });
await expect(invalidImportPath).toBeVisible();
const collectionPathAsImportPath = page.getByRole('cell', { name: '.', exact: true });
const collectionPathName = page.getByRole('cell', { name: 'collection', exact: true });
// Invalid messages using test IDs
const invalidProtoFilesMessage = page.getByTestId('protobuf-invalid-files-message');
const invalidImportPathsMessage = page.getByTestId('protobuf-invalid-import-paths-message');
await expect(invalidProtoFilesMessage).toBeVisible();
await expect(invalidImportPathsMessage).toBeVisible();
await expect(collectionPathAsImportPath).toBeVisible();
await expect(collectionPathName).toBeVisible();
await page.getByRole('row', { name: 'invalid-file-path.proto' }).getByTestId('protobuf-remove-file-button').click();
await expect(page.getByRole('cell', { name: 'invalid-file-path.proto', exact: true })).not.toBeVisible();
await expect(invalidProtoFilesMessage).not.toBeVisible();
await page.getByRole('row', { name: '../protos/invalid-import-path' }).getByTestId('protobuf-remove-import-path-button').click();
await expect(page.getByRole('cell', { name: '../protos/invalid-import-path', exact: true })).not.toBeVisible();
await expect(invalidImportPathsMessage).not.toBeVisible();
});
test('order.proto loads methods successfully when selected', async ({ pageWithUserData: page }) => {
await page.locator('#sidebar-collection-name').filter({ hasText: 'Grpcbin' }).click();
await page.getByText('HelloService').click();
await page.getByText('SayHello').click();
// Wait for gRPC query URL container to load
const grpcQueryUrlContainer = page.getByTestId('grpc-query-url-container');
await grpcQueryUrlContainer.waitFor({ state: 'visible' });
await page.getByText('Using Reflection').click();
await page.getByText('Proto FileReflection').click();
// Use more specific selector for proto file selection
await page.locator('div').filter({ hasText: /^order\.proto\.\.\/protos\/services\/order\.proto$/ }).first().click();
// Use test ID for method selection
const grpcMethodsDropdown = page.getByTestId('grpc-methods-dropdown');
await grpcMethodsDropdown.click();
const method = page.getByTestId('grpc-method-item').filter({ hasText: /^CreateOrderunary$/ }).first();
await expect(method).toBeVisible();
await method.click();
await page.getByRole('tab', { name: 'gRPC sayHello' }).getByRole('img').click();
await page.getByRole('button', { name: 'Don\'t Save' }).click();
});
test('product.proto fails to load methods when selected', async ({ pageWithUserData: page }) => {
await page.locator('#sidebar-collection-name').filter({ hasText: 'Grpcbin' }).click();
await page.getByText('HelloService').click();
await page.getByText('SayHello').click();
// Wait for gRPC query URL container to load
const grpcQueryUrlContainer = page.getByTestId('grpc-query-url-container');
await grpcQueryUrlContainer.waitFor({ state: 'visible' });
await page.getByText('Using Reflection').click();
await page.getByText('Proto FileReflection').click();
// Use more specific selector for proto file selection
await page.locator('div').filter({ hasText: /^product\.proto\.\.\/protos\/services\/product\.proto$/ }).first().click();
const loadedMethodsMessage = await page.getByText('Failed to load gRPC methods: Unknown error').first().isVisible();
expect(loadedMethodsMessage).toBe(true);
// Check that methods dropdown is not visible when loading fails
const methodsDropdown = page.getByTestId('grpc-methods-dropdown');
await expect(methodsDropdown).not.toBeVisible();
await page.getByRole('tab', { name: 'gRPC sayHello' }).getByRole('img').click();
await page.getByRole('button', { name: 'Don\'t Save' }).click();
});
test('product.proto successfully loads methods once import path is provided', async ({ pageWithUserData: page }) => {
await page.locator('#sidebar-collection-name').filter({ hasText: 'Grpcbin' }).click();
// add import path within collection setting, protobuf tab
await page.getByRole('tab', { name: 'Protobuf' }).click();
// Wait for protobuf settings to load
const protobufImportPathsSection = page.getByTestId('protobuf-import-paths-section');
await protobufImportPathsSection.waitFor({ state: 'visible' });
const importPathTable = page.getByTestId('protobuf-import-paths-table');
await expect(importPathTable).toBeVisible();
// Use test ID for checkbox
const checkbox = page.getByRole('row', { name: 'Enable this import path types' }).getByTestId('protobuf-import-path-checkbox');
await checkbox.click();
// Now test that product.proto can load methods successfully
await page.getByText('HelloService').click();
await page.getByText('SayHello').click();
// Wait for gRPC query URL container to load
const grpcQueryUrlContainer = page.getByTestId('grpc-query-url-container');
await grpcQueryUrlContainer.waitFor({ state: 'visible' });
await page.getByText('Using Reflection').click();
await page.getByText('Proto FileReflection').click();
// Use more specific selector for proto file selection
await page.locator('div').filter({ hasText: /^product\.proto\.\.\/protos\/services\/product\.proto$/ }).first().click();
const grpcMethodsDropdown = page.getByTestId('grpc-methods-dropdown');
await grpcMethodsDropdown.click();
const method = page.getByTestId('grpc-methods-list').filter({ hasText: 'CreateProductunary' }).first();
await expect(method).toBeVisible();
await method.click();
// Clean up
await page.getByRole('tab', { name: 'gRPC sayHello' }).getByRole('img').click();
await page.getByRole('button', { name: 'Don\'t Save' }).click();
});
});