mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2025-11-29 19:08:33 +08:00
chore: strip data-testid on prod
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { AuthTestUtils } from '../../support/auth-utils';
|
import { AuthTestUtils } from '../../support/auth-utils';
|
||||||
import { TestTool } from '../../support/page-utils';
|
import { TestTool } from '../../support/page-utils';
|
||||||
import { PageSelectors, ViewActionSelectors, SpaceSelectors, waitForReactUpdate } from '../../support/selectors';
|
import { PageSelectors, waitForReactUpdate } from '../../support/selectors';
|
||||||
|
|
||||||
describe('More Page Actions', () => {
|
describe('More Page Actions', () => {
|
||||||
const APPFLOWY_BASE_URL = Cypress.env('APPFLOWY_BASE_URL');
|
const APPFLOWY_BASE_URL = Cypress.env('APPFLOWY_BASE_URL');
|
||||||
@@ -136,62 +136,4 @@ describe('More Page Actions', () => {
|
|||||||
|
|
||||||
cy.task('log', 'Page successfully duplicated');
|
cy.task('log', 'Page successfully duplicated');
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should open Change Icon popover from More actions', () => {
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should remove icon via Change Icon popover', () => {
|
|
||||||
// TestTool.morePageActionsChangeIcon();
|
|
||||||
|
|
||||||
// cy.get('[role="dialog"]').within(() => {
|
|
||||||
// cy.contains('button', 'Remove').click();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TestTool.getModal().should('not.exist');
|
|
||||||
// cy.get('.view-icon').should('not.exist');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should upload a custom icon via Change Icon popover', () => {
|
|
||||||
// TestTool.morePageActionsChangeIcon();
|
|
||||||
|
|
||||||
// cy.get('[role="dialog"]').within(() => {
|
|
||||||
// cy.get('input[type="file"]').attachFile('test-icon.png');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TestTool.getModal().should('not.exist');
|
|
||||||
// cy.get('.view-icon').should('exist');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should open page in a new tab from More actions', () => {
|
|
||||||
// cy.window().then((win) => {
|
|
||||||
// cy.stub(win, 'open').as('open');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// TestTool.morePageActionsOpenNewTab();
|
|
||||||
// cy.get('@open').should('be.called');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should duplicate page from More actions and show success toast', () => {
|
|
||||||
// TestTool.morePageActionsDuplicate();
|
|
||||||
// cy.wait(2000);
|
|
||||||
// TestTool.getPageByName('Get started').should('have.length', 2);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should move page to another space from More actions', () => {
|
|
||||||
// TestTool.morePageActionsMoveTo();
|
|
||||||
|
|
||||||
// cy.get('[role="dialog"]').within(() => {
|
|
||||||
// TestTool.getSpaceItems().first().click();
|
|
||||||
// });
|
|
||||||
// cy.wait(2000);
|
|
||||||
// TestTool.getPageByName('Get started').should('be.visible');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should delete page from More actions and confirm deletion', () => {
|
|
||||||
// TestTool.morePageActionsDelete();
|
|
||||||
// TestTool.confirmPageDeletion();
|
|
||||||
// cy.wait(2000);
|
|
||||||
// TestTool.getPageByName('Get started').should('not.exist');
|
|
||||||
// });
|
|
||||||
});
|
});
|
||||||
82
vite-plugin-strip-testid.ts
Normal file
82
vite-plugin-strip-testid.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { Plugin } from 'vite';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vite plugin to strip data-testid attributes from production builds
|
||||||
|
* This reduces bundle size and removes test-specific attributes from production code
|
||||||
|
*/
|
||||||
|
export function stripTestIdPlugin(): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'strip-test-id',
|
||||||
|
apply: 'build', // Only apply during build, not dev
|
||||||
|
transform(code: string, id: string) {
|
||||||
|
// Skip node_modules to avoid transforming external libraries
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only process .tsx and .jsx files from our source
|
||||||
|
if (!id.match(/src.*\.(tsx|jsx)$/)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only strip in production builds
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let transformedCode = code;
|
||||||
|
let hasChanges = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Pattern 1: Simple string attributes: data-testid="value" or data-testid='value'
|
||||||
|
// This is the safest pattern to remove
|
||||||
|
const simpleStringPattern = /\s+data-testid\s*=\s*["'][^"']*["']/g;
|
||||||
|
const matches = transformedCode.match(simpleStringPattern);
|
||||||
|
if (matches && matches.length > 0) {
|
||||||
|
console.log(`Stripping ${matches.length} data-testid attributes from ${id}`);
|
||||||
|
transformedCode = transformedCode.replace(simpleStringPattern, '');
|
||||||
|
hasChanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern 2: Simple expressions without nested braces: data-testid={variable}
|
||||||
|
const simpleExpressionPattern = /\s+data-testid\s*=\s*\{[^{}]+\}/g;
|
||||||
|
const exprMatches = transformedCode.match(simpleExpressionPattern);
|
||||||
|
if (exprMatches && exprMatches.length > 0) {
|
||||||
|
console.log(`Stripping ${exprMatches.length} data-testid expressions from ${id}`);
|
||||||
|
transformedCode = transformedCode.replace(simpleExpressionPattern, '');
|
||||||
|
hasChanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern 3: Template literals: data-testid={`value-${id}`}
|
||||||
|
const templatePattern = /\s+data-testid\s*=\s*\{`[^`]*`\}/g;
|
||||||
|
if (templatePattern.test(transformedCode)) {
|
||||||
|
transformedCode = transformedCode.replace(templatePattern, '');
|
||||||
|
hasChanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasChanges) {
|
||||||
|
// Quick validation: check for obvious syntax errors
|
||||||
|
// Count opening and closing braces to ensure we didn't break anything
|
||||||
|
const openBraces = (transformedCode.match(/\{/g) || []).length;
|
||||||
|
const closeBraces = (transformedCode.match(/\}/g) || []).length;
|
||||||
|
|
||||||
|
if (openBraces !== closeBraces) {
|
||||||
|
console.warn(`Warning: Brace mismatch after transformation in ${id}. Skipping transformation.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: transformedCode,
|
||||||
|
map: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing ${id}:`, error);
|
||||||
|
// Return null to skip transformation on error
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { createHtmlPlugin } from 'vite-plugin-html';
|
|||||||
import istanbul from 'vite-plugin-istanbul';
|
import istanbul from 'vite-plugin-istanbul';
|
||||||
import svgr from 'vite-plugin-svgr';
|
import svgr from 'vite-plugin-svgr';
|
||||||
import { totalBundleSize } from 'vite-plugin-total-bundle-size';
|
import { totalBundleSize } from 'vite-plugin-total-bundle-size';
|
||||||
|
import { stripTestIdPlugin } from './vite-plugin-strip-testid';
|
||||||
|
|
||||||
const resourcesPath = path.resolve(__dirname, '../resources');
|
const resourcesPath = path.resolve(__dirname, '../resources');
|
||||||
const isDev = process.env.NODE_ENV === 'development';
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
@@ -17,6 +18,8 @@ const isTest = process.env.NODE_ENV === 'test' || process.env.COVERAGE === 'true
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
|
// Strip data-testid attributes in production builds
|
||||||
|
isProd ? stripTestIdPlugin() : undefined,
|
||||||
createHtmlPlugin({
|
createHtmlPlugin({
|
||||||
inject: {
|
inject: {
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
Reference in New Issue
Block a user