Skip to content

Commit 9ef591f

Browse files
Merge pull request #301 from contentstack/staging
Merge Test cases to main
2 parents 27efb0c + a570266 commit 9ef591f

File tree

89 files changed

+21307
-973
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+21307
-973
lines changed

.gitignore

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,34 @@ tap-html.html
1212
coverage
1313
.env
1414
.dccache
15-
dist/*
15+
dist/
16+
.idea/
17+
.vscode/
18+
*.swp
19+
*.swo
20+
*~
21+
.cache
22+
test-results/
23+
24+
# Build artifacts (should only be in dist/)
25+
src/**/*.js
26+
src/**/*.js.map
27+
28+
# Browser test bundle (generated)
29+
test/e2e/sdk-browser-bundle.js
30+
test/e2e/sdk-browser-bundle.js.map
31+
docs
32+
reports
33+
34+
# Bundler test artifacts (regenerated on test run)
35+
test/bundlers/**/.next/
36+
test/bundlers/**/dist/
37+
test/bundlers/**/node_modules/
38+
test/bundlers/**/package-lock.json
39+
40+
# Temporary internal scripts
41+
test/docs/*.js
42+
test/docs/*.mjs
43+
test/docs/sanity-report*
1644
*.log
1745
.nx/

.talismanrc

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
fileignoreconfig:
2+
- filename: test/browser/import.spec.ts
3+
checksum: 2e9a157e28b0ce71c4b6422c6b457996a2e6785a1ef591c8bb35276b3471a5d0
4+
- filename: scripts/test-bundlers.js
5+
checksum: 4a85cdc2f456d2f9d64d96eedaeddd34f192f243f352132957b1a9c0e979d635
6+
- filename: test/browser/helpers/browser-stack-instance.ts
7+
checksum: 333fdbd1229022736e6e3262c7f275cb22534ec149d4e9a8270f0745b60d8661
8+
- filename: scripts/validate-browser-safe.js
9+
checksum: 769b95cf55a6cf8455d057a662a8071286faf62a75862e3317d79367fe1ed5b4
10+
- filename: test/browser/initialization.spec.ts
11+
checksum: 4054847ebfcc980299240a27d0aa30c1f43a9482e6ba39ac0af6126e7db9e04a
12+
- filename: test/e2e/browser-integration.spec.ts
13+
checksum: 6646595d48bfaec3d9de111b22b36cf0925b33e18df55b068181c0bb81c1862b
14+
- filename: test/browser/real-api-calls.spec.ts
15+
checksum: 514930cdde28cdc8b37ab054031260d5703dc8bdf777906dd5f9baa270ab7c3a
216
- filename: package-lock.json
317
checksum: e0a6679bfc6556fb7a8424c3f8eb0cec62f2cc871ad544f691fa064ddec30db7
418
- filename: test/unit/utils.spec.ts
@@ -19,4 +33,37 @@ fileignoreconfig:
1933
checksum: dc07b0a8111fd8e155b99f56c31ccdddd4f46c86f1b162b17d73e15dfed8e3c8
2034
- filename: test/unit/retry-configuration.spec.ts
2135
checksum: 359c8601c6205a65f3395cc209a93b278dfe7f5bb547c91b2eeab250b2c85aa3
22-
version: ""
36+
- filename: package-lock.json
37+
checksum: 993afd503e9f5d399fac30ae230cb47538cec2c61c5364e88be72726fb723dda
38+
ignore_detectors: [ base64, filecontent ]
39+
- filename: src/lib/global-field.ts
40+
checksum: 70b9652bcba16ddc4d853ac212ad909a8ecfc76f491c55a05e4e3cdf9ce476b5
41+
- filename: src/lib/content-type.ts
42+
checksum: 1dc0fa53ae209efb67d68a01493822e9dec560799f8309329213dae69459655f
43+
- filename: src/lib/stack.ts
44+
checksum: 145dd6add876a771a9a6ba024f57ef2c4b46a911fe1bf3885a69cf1f6c9dd72d
45+
- filename: src/lib/entry.ts
46+
checksum: 1c64ccf19226873d068d6896028bfb74546c1cfd993779515bccfcc747180ca0
47+
- filename: src/lib/error-messages.ts
48+
checksum: 3b960af19f3ba302522e912616b147b11d63dfe3f7ad2e0cf2de807815ee236a
49+
- filename: src/lib/global-field-query.ts
50+
checksum: 824c54061b80236380e776640e7f52f45164230bcc0ee88de302b30e9f83297f
51+
- filename: src/lib/base-query.ts
52+
checksum: 8d67435121581d43ba9c5f544daf30a0579b7faa7c8661000d8d37ddfc172112
53+
- filename: test/unit/base-query.spec.ts
54+
checksum: ceaceb1d65965b151edc9fc11d5a226460328b1913319994df51ca1b453cd6af
55+
- filename: src/lib/entries.ts
56+
checksum: 3ffe426234ef710d0fcfd8e41ca57f61ce6bc44298ee7dde6f4530fa3c16d2ee
57+
- filename: test/unit/error-messages.spec.ts
58+
checksum: b64be136b19890aa9e9000bac7df6eb1188828ee4b740d5c756396699716c428
59+
- filename: test/api/modular-blocks.spec.ts
60+
checksum: 1e536b0409f05f2d5c1d6e87b0ec4bda2c3fde9bc4ff331406f33464a26cff55
61+
- filename: test/unit/centralized-error-handling.spec.ts
62+
checksum: 66a5eb520414bd71da331338bfb4faa2fc9f233eadf0eb18ddd7915db6849238
63+
- filename: src/lib/query.ts
64+
checksum: f7200cb6e3b9ff681439482faaf882781dfb5f6ab6fefd4c98203ba8bf30d5e6
65+
- filename: test/api/base-query-casting.specs.ts
66+
checksum: 9185df498914e2966d78d9d216acaaa910d43cd7ac9a5e9a26e7241ac9edc9b5
67+
- filename: test/reporting/generate-unified-report.js
68+
checksum: 9e7a4696561b790cb93f3be8406a70ec6fdc90a3f8bbb9739504495690158fe3
69+
version: "1.0"

jest.config.browser.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* eslint-disable */
2+
/**
3+
* Browser Environment Jest Configuration
4+
*
5+
* Purpose: Test SDK in browser-like environment (jsdom) to catch Node.js-only API usage
6+
* This configuration will FAIL if code tries to use: fs, path, crypto, etc.
7+
*/
8+
export default {
9+
displayName: "browser-environment",
10+
preset: "./jest.preset.js",
11+
12+
// ⚠️ CRITICAL: Use jsdom (browser) instead of node environment
13+
testEnvironment: "jest-environment-jsdom",
14+
15+
// Only run browser-specific tests
16+
testMatch: ["**/test/browser/**/*.spec.ts"],
17+
18+
transform: {
19+
"^.+\\.[tj]s$": [
20+
"ts-jest",
21+
{
22+
tsconfig: {
23+
// Browser-only libs
24+
lib: ["dom", "dom.iterable", "es2020"],
25+
// Include jest types for test files
26+
types: ["jest", "@types/node"],
27+
target: "es2020",
28+
module: "commonjs",
29+
esModuleInterop: true,
30+
skipLibCheck: true
31+
},
32+
diagnostics: {
33+
warnOnly: true
34+
}
35+
},
36+
],
37+
},
38+
39+
moduleFileExtensions: ["ts", "js", "html"],
40+
41+
// Browser globals (available in jsdom)
42+
setupFilesAfterEnv: ['<rootDir>/jest.setup.browser.ts'],
43+
44+
// Collect coverage separately for browser tests
45+
collectCoverage: true,
46+
coverageDirectory: "./reports/browser-environment/coverage/",
47+
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.spec.ts", "!src/index.ts"],
48+
49+
// Timeout for browser environment tests
50+
testTimeout: 10000,
51+
52+
// Don't mock Node.js modules globally - let natural browser environment catch issues
53+
// moduleNameMapper: {},
54+
55+
reporters: [
56+
"default",
57+
[
58+
"jest-html-reporter",
59+
{
60+
pageTitle: "Browser Environment Test Report",
61+
outputPath: "reports/browser-environment/index.html",
62+
includeFailureMsg: true,
63+
includeConsoleLog: true,
64+
},
65+
],
66+
],
67+
};
68+

jest.config.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ export default {
1919
// branches: 95,
2020
// }
2121
},
22+
// Use single worker to avoid circular JSON serialization issues with error objects
23+
// This prevents "Jest worker encountered 4 child process exceptions" errors
24+
maxWorkers: 1,
25+
// Increase timeout for integration tests that may take longer
26+
testTimeout: 30000,
27+
// Global setup file to suppress expected SDK validation errors
28+
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
2229
reporters: [
2330
"default",
2431
[
@@ -36,6 +43,9 @@ export default {
3643
publicPath: "./reports/contentstack-delivery/html",
3744
filename: "index.html",
3845
expand: true,
46+
// Enable console log capture in reports
47+
enableMergeData: true,
48+
dataMergeLevel: 2,
3949
},
4050
],
4151
[
@@ -50,5 +60,12 @@ export default {
5060
titleTemplate: "{title}",
5161
},
5262
],
63+
// JSON reporter to capture console logs for unified report
64+
[
65+
"./test/reporting/jest-json-reporter.cjs",
66+
{
67+
outputPath: "test-results/jest-results.json",
68+
},
69+
],
5370
],
5471
};

jest.preset.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1-
import nxPreset from '@nrwl/jest/preset/index.js';
2-
3-
export default { ...nxPreset };
1+
export default {
2+
testEnvironment: 'node',
3+
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
4+
transform: {
5+
'^.+\\.ts$': 'ts-jest',
6+
},
7+
moduleFileExtensions: ['ts', 'js', 'json'],
8+
collectCoverageFrom: [
9+
'src/**/*.ts',
10+
'!src/**/*.d.ts',
11+
'!src/index.ts',
12+
],
13+
coverageDirectory: 'coverage',
14+
coverageReporters: ['text', 'lcov', 'html'],
15+
};

jest.setup.browser.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Browser Environment Test Setup
3+
*
4+
* Sets up browser-like globals and polyfills for testing
5+
*/
6+
7+
// jsdom provides fetch natively in newer versions
8+
// No need to import node-fetch
9+
10+
// Suppress expected console errors during tests
11+
const originalError = console.error;
12+
const originalWarn = console.warn;
13+
14+
beforeAll(() => {
15+
console.error = (...args: any[]) => {
16+
// Suppress specific expected errors
17+
const message = args[0]?.toString() || '';
18+
if (
19+
message.includes('Not implemented: HTMLFormElement.prototype.submit') ||
20+
message.includes('Not implemented: navigation')
21+
) {
22+
return;
23+
}
24+
originalError.call(console, ...args);
25+
};
26+
27+
console.warn = (...args: any[]) => {
28+
// Suppress specific expected warnings
29+
const message = args[0]?.toString() || '';
30+
if (message.includes('jsdom')) {
31+
return;
32+
}
33+
originalWarn.call(console, ...args);
34+
};
35+
});
36+
37+
afterAll(() => {
38+
console.error = originalError;
39+
console.warn = originalWarn;
40+
});
41+
42+
// Add custom matchers for browser testing if needed
43+
expect.extend({
44+
toBeBrowserSafe(received: any) {
45+
const forbidden = ['fs', 'path', 'crypto', 'Buffer', 'process'];
46+
const receivedString = JSON.stringify(received);
47+
48+
for (const api of forbidden) {
49+
if (receivedString.includes(api)) {
50+
return {
51+
pass: false,
52+
message: () => `Expected code to be browser-safe, but found Node.js API: ${api}`,
53+
};
54+
}
55+
}
56+
57+
return {
58+
pass: true,
59+
message: () => 'Code is browser-safe',
60+
};
61+
},
62+
});
63+

jest.setup.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Global Jest Setup File
3+
*
4+
* 1. Captures console logs for test reports
5+
* 2. Suppresses expected SDK validation errors to reduce console noise during tests.
6+
*/
7+
import * as fs from 'fs';
8+
import * as path from 'path';
9+
10+
// Store captured console logs
11+
interface ConsoleLog {
12+
type: 'log' | 'warn' | 'error' | 'info' | 'debug';
13+
message: string;
14+
timestamp: string;
15+
testFile?: string;
16+
}
17+
18+
declare global {
19+
var __CONSOLE_LOGS__: ConsoleLog[];
20+
var __CURRENT_TEST_FILE__: string;
21+
}
22+
23+
// Initialize global console log storage
24+
global.__CONSOLE_LOGS__ = [];
25+
global.__CURRENT_TEST_FILE__ = '';
26+
27+
// Store original console methods
28+
const originalConsole = {
29+
log: console.log,
30+
warn: console.warn,
31+
error: console.error,
32+
info: console.info,
33+
debug: console.debug
34+
};
35+
36+
// List of expected SDK validation errors to suppress
37+
const expectedErrors = [
38+
'Invalid key:', // From query.search() validation
39+
'Invalid value (expected string or number):', // From query.equalTo() validation
40+
'Argument should be a String or an Array.', // From entry/entries.includeReference() validation
41+
'Invalid fieldUid:', // From asset query validation
42+
];
43+
44+
// Helper to capture and optionally forward console output
45+
function captureConsole(type: 'log' | 'warn' | 'error' | 'info' | 'debug') {
46+
return (...args: any[]) => {
47+
const message = args.map(arg =>
48+
typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
49+
).join(' ');
50+
51+
// Store the log
52+
global.__CONSOLE_LOGS__.push({
53+
type,
54+
message,
55+
timestamp: new Date().toISOString(),
56+
testFile: global.__CURRENT_TEST_FILE__
57+
});
58+
59+
// For errors, check if it's expected (suppress if so)
60+
if (type === 'error') {
61+
const isExpectedError = expectedErrors.some(pattern => message.includes(pattern));
62+
if (!isExpectedError) {
63+
originalConsole[type].apply(console, args);
64+
}
65+
} else {
66+
// Forward other logs normally
67+
originalConsole[type].apply(console, args);
68+
}
69+
};
70+
}
71+
72+
// Override console methods to capture logs
73+
console.log = captureConsole('log');
74+
console.warn = captureConsole('warn');
75+
console.error = captureConsole('error');
76+
console.info = captureConsole('info');
77+
console.debug = captureConsole('debug');
78+
79+
// After all tests complete, write logs to file
80+
afterAll(() => {
81+
const logsPath = path.resolve(__dirname, 'test-results', 'console-logs.json');
82+
const logsDir = path.dirname(logsPath);
83+
84+
if (!fs.existsSync(logsDir)) {
85+
fs.mkdirSync(logsDir, { recursive: true });
86+
}
87+
88+
// Append to existing logs (in case of multiple test files)
89+
let existingLogs: ConsoleLog[] = [];
90+
if (fs.existsSync(logsPath)) {
91+
try {
92+
existingLogs = JSON.parse(fs.readFileSync(logsPath, 'utf8'));
93+
} catch {
94+
existingLogs = [];
95+
}
96+
}
97+
98+
const allLogs = [...existingLogs, ...global.__CONSOLE_LOGS__];
99+
fs.writeFileSync(logsPath, JSON.stringify(allLogs, null, 2));
100+
101+
// Clear for next file
102+
global.__CONSOLE_LOGS__ = [];
103+
});
104+

0 commit comments

Comments
 (0)