diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5fc8f9d55e5c..8fd537898b28 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1035,14 +1035,19 @@ jobs: overwrite: true retention-days: 7 + - name: Pre-process E2E Test Dumps + run: | + node ./scripts/normalize-e2e-test-dump-transaction-events.js + - name: Upload E2E Test Event Dumps uses: actions/upload-artifact@v4 if: always() with: - name: e2e-test-event-dumps + name: E2E Test Dump (${{ matrix.label || matrix.test-application }}) path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps overwrite: true retention-days: 7 + if-no-files-found: ignore - name: Upload test results to Codecov if: cancelled() == false @@ -1083,10 +1088,6 @@ jobs: 'react-send-to-sentry', 'node-express-send-to-sentry', 'debug-id-sourcemaps', - 'nextjs-app-dir', - 'nextjs-13', - 'nextjs-14', - 'nextjs-15', ] build-command: - false @@ -1184,6 +1185,20 @@ jobs: timeout-minutes: 10 run: pnpm ${{ matrix.assert-command || 'test:assert' }} + - name: Pre-process E2E Test Dumps + run: | + node ./scripts/normalize-e2e-test-dump-transaction-events.js + + - name: Upload E2E Test Event Dumps + uses: actions/upload-artifact@v4 + if: always() + with: + name: E2E Test Dump (${{ matrix.label || matrix.test-application }}) + path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps + overwrite: true + retention-days: 7 + if-no-files-found: ignore + - name: Deploy Astro to Cloudflare uses: cloudflare/pages-action@v1 if: matrix.test-application == 'cloudflare-astro' diff --git a/packages/nextjs/src/config/loaders/wrappingLoader.ts b/packages/nextjs/src/config/loaders/wrappingLoader.ts index d3c1d62c9330..e298a459d16e 100644 --- a/packages/nextjs/src/config/loaders/wrappingLoader.ts +++ b/packages/nextjs/src/config/loaders/wrappingLoader.ts @@ -182,8 +182,10 @@ export default function wrappingLoader( const componentTypeMatch = path.posix .normalize(path.relative(appDir, this.resourcePath)) + // Replace all backslashes with forward slashes (windows) + .replace(/\\/g, '/') // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor - .match(new RegExp(`/\\/?([^/]+)\\.(?:${pageExtensionRegex})$`)); + .match(new RegExp(`(?:^|/)?([^/]+)\\.(?:${pageExtensionRegex})$`)); if (componentTypeMatch && componentTypeMatch[1]) { let componentType: ServerComponentContext['componentType']; diff --git a/scripts/normalize-e2e-test-dump-transaction-events.js b/scripts/normalize-e2e-test-dump-transaction-events.js index ba06a63fa020..771dcccd8f87 100644 --- a/scripts/normalize-e2e-test-dump-transaction-events.js +++ b/scripts/normalize-e2e-test-dump-transaction-events.js @@ -1,81 +1,95 @@ +// @ts-check /* eslint-disable no-console */ const fs = require('fs'); const path = require('path'); +const glob = require('glob'); + +glob.glob( + '../dev-packages/e2e-tests/test-applications/*/event-dumps/*.dump', + { + cwd: __dirname, + absolute: true, + }, + (err, dumpPaths) => { + if (err) { + throw err; + } -if (process.argv.length < 4) { - throw new Error('Please provide an input and output file path as an argument.'); -} - -const resolvedInputPath = path.resolve(process.argv[2]); -const resolvedOutputPath = path.resolve(process.argv[3]); - -const fileContents = fs.readFileSync(resolvedInputPath, 'utf8'); - -const transactionNodes = []; - -fileContents.split('\n').forEach(serializedEnvelope => { - let envelope; - try { - envelope = JSON.parse(serializedEnvelope); - } catch (e) { - return; - // noop - } + dumpPaths.forEach(dumpPath => { + const fileContents = fs.readFileSync(dumpPath, 'utf8'); - const envelopeItems = envelope[1]; - - envelopeItems.forEach(([envelopeItemHeader, transaction]) => { - if (envelopeItemHeader.type === 'transaction') { - const rootNode = { - runtime: transaction.contexts.runtime?.name, - op: transaction.contexts.trace.op, - name: transaction.transaction, - children: [], - }; - - const spanMap = new Map(); - spanMap.set(transaction.contexts.trace.span_id, rootNode); - - transaction.spans.forEach(span => { - const node = { - op: span.data['sentry.op'], - name: span.description, - parent_span_id: span.parent_span_id, - children: [], - }; - spanMap.set(span.span_id, node); - }); + const transactionNodes = []; - transaction.spans.forEach(span => { - const node = spanMap.get(span.span_id); - if (node && node.parent_span_id) { - const parentNode = spanMap.get(node.parent_span_id); - parentNode.children.push(node); + fileContents.split('\n').forEach(serializedEnvelope => { + let envelope; + try { + envelope = JSON.parse(serializedEnvelope); + } catch (e) { + return; + // noop } - }); - transactionNodes.push(rootNode); - } - }); -}); - -const output = transactionNodes - .sort((a, b) => { - const aSerialized = serializeNode(a); - const bSerialized = serializeNode(b); - if (aSerialized < bSerialized) { - return -1; - } else if (aSerialized > bSerialized) { - return 1; - } else { - return 0; - } - }) - .map(node => buildDeterministicStringFromNode(node)) - .join('\n\n-----------------------\n\n'); + const envelopeItems = envelope[1]; + + envelopeItems.forEach(([envelopeItemHeader, transaction]) => { + if (envelopeItemHeader.type === 'transaction') { + const rootNode = { + runtime: transaction.contexts.runtime?.name, + op: transaction.contexts.trace.op, + name: transaction.transaction, + children: [], + }; + + const spanMap = new Map(); + spanMap.set(transaction.contexts.trace.span_id, rootNode); + + transaction.spans.forEach(span => { + const node = { + op: span.data['sentry.op'], + name: span.description, + parent_span_id: span.parent_span_id, + children: [], + }; + spanMap.set(span.span_id, node); + }); + + transaction.spans.forEach(span => { + const node = spanMap.get(span.span_id); + if (node && node.parent_span_id) { + const parentNode = spanMap.get(node.parent_span_id); + parentNode.children.push(node); + } + }); + + transactionNodes.push(rootNode); + } + }); + }); -fs.writeFileSync(resolvedOutputPath, output, 'utf-8'); + const output = transactionNodes + .sort((a, b) => { + const aSerialized = serializeNode(a); + const bSerialized = serializeNode(b); + if (aSerialized < bSerialized) { + return -1; + } else if (aSerialized > bSerialized) { + return 1; + } else { + return 0; + } + }) + .map(node => buildDeterministicStringFromNode(node)) + .join('\n\n-----------------------\n\n'); + + fs.writeFileSync( + path.join(path.dirname(dumpPath), `normalized-transactions-${path.basename(dumpPath, '.dump')}.txt`), + output, + 'utf-8', + ); + }); + }, +); // ------- utility fns ----------