Skip to content

Commit 5bebab9

Browse files
committed
check-working
1 parent ebcfc81 commit 5bebab9

17 files changed

+985
-271
lines changed

.github/workflows/javascript.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,31 @@ jobs:
4040
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
4141
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
4242

43+
browser_tests:
44+
runs-on: macos-latest
45+
strategy:
46+
matrix:
47+
browser: ['chrome', 'firefox', 'edge', 'safari']
48+
env:
49+
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
50+
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
51+
BROWSERSTACK_LOCAL: 'true'
52+
USE_LOCAL_BROWSER: 'false'
53+
TEST_BROWSER: ${{ matrix.browser }}
54+
steps:
55+
- uses: actions/checkout@v3
56+
- name: Set up Node
57+
uses: actions/setup-node@v3
58+
with:
59+
node-version: 20
60+
cache: 'npm'
61+
cache-dependency-path: ./package-lock.json
62+
- name: Browser tests - ${{ matrix.browser }}
63+
working-directory: .
64+
run: |
65+
npm install
66+
npm run test-vitest-browser
67+
4368
# crossbrowser_and_umd_unit_tests:
4469
# runs-on: ubuntu-latest
4570
# env:

lib/event_processor/batch_event_processor.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ describe('BatchEventProcessor', async () => {
365365
expect(eventStore.size()).toEqual(10);
366366

367367
const eventsInStore = Array.from(eventStore.getAll().values())
368-
.sort((a, b) => a < b ? -1 : 1).map(e => e.event);
368+
.sort((a, b) => a.id < b.id ? -1 : 1).map(e => e.event);
369369

370370
expect(events).toEqual(eventsInStore);
371371
});

lib/event_processor/event_processor_factory.browser.spec.ts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@
1515
*/
1616
import { beforeEach, describe, expect, it, vi } from 'vitest';
1717

18+
// vitest does not handle Class mock well when transpiling to ES6 with { spy: true }.
19+
// So we provide manual mocks here.
20+
// Also importOriginal() does not work in browser mode, so we mock every export explicitly.
21+
1822
vi.mock('./default_dispatcher.browser', () => {
1923
return { default: {} };
2024
});
2125

22-
vi.mock('./event_processor_factory', async (importOriginal) => {
26+
vi.mock('./event_processor_factory', () => {
27+
// Create a unique symbol for wrapping/unwrapping
28+
const eventProcessorSymbol = Symbol('eventProcessor');
29+
2330
const getBatchEventProcessor = vi.fn().mockImplementation(() => {
2431
return {};
2532
});
@@ -29,25 +36,54 @@ vi.mock('./event_processor_factory', async (importOriginal) => {
2936
const getForwardingEventProcessor = vi.fn().mockImplementation(() => {
3037
return {};
3138
});
32-
const original: any = await importOriginal();
33-
return { ...original, getBatchEventProcessor, getOpaqueBatchEventProcessor, getForwardingEventProcessor, FAILED_EVENT_RETRY_INTERVAL: 20000 };
39+
40+
return {
41+
INVALID_EVENT_DISPATCHER: 'Invalid event dispatcher',
42+
FAILED_EVENT_RETRY_INTERVAL: 20000,
43+
getPrefixEventStore: vi.fn(),
44+
validateEventDispatcher: vi.fn(),
45+
getBatchEventProcessor,
46+
wrapEventProcessor: vi.fn((ep) => ({ [eventProcessorSymbol]: ep })),
47+
getOpaqueBatchEventProcessor,
48+
extractEventProcessor: vi.fn((ep) => ep?.[eventProcessorSymbol]),
49+
getForwardingEventProcessor,
50+
__platforms: ['__universal__'],
51+
};
3452
});
3553

3654
vi.mock('../utils/cache/local_storage_cache.browser', () => {
3755
return { LocalStorageCache: vi.fn() };
3856
});
3957

40-
vi.mock('./event_store', async (importOriginal) => {
41-
const actual: any = await importOriginal()
58+
vi.mock('./event_store', () => {
4259
return {
43-
...actual,
60+
DEFAULT_MAX_EVENTS_IN_STORE: 500,
61+
DEFAULT_STORE_TTL: 10 * 24 * 60 * 60 * 1000,
62+
EVENT_STORE_PREFIX: 'optly_event:',
4463
EventStore: vi.fn(),
45-
}
64+
__platforms: ['__universal__'],
65+
};
4666
});
4767

48-
vi.mock('../utils/cache/store', async (importOriginal) => {
49-
const actual: any = await importOriginal()
50-
return { ...actual, SyncPrefixStore: vi.fn(), AsyncPrefixStore: vi.fn() };
68+
vi.mock('../utils/cache/store', () => {
69+
// Create base abstract classes
70+
class SyncStoreWithBatchedGet {
71+
operation = 'sync' as const;
72+
}
73+
74+
class AsyncStoreWithBatchedGet {
75+
operation = 'async' as const;
76+
}
77+
78+
return {
79+
SyncStoreWithBatchedGet,
80+
AsyncStoreWithBatchedGet,
81+
getBatchedSync: vi.fn(),
82+
getBatchedAsync: vi.fn(),
83+
SyncPrefixStore: vi.fn(),
84+
AsyncPrefixStore: vi.fn(),
85+
__platforms: ['__universal__'],
86+
};
5187
});
5288

5389

lib/event_processor/event_processor_factory.react_native.spec.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ vi.mock('@react-native-community/netinfo', () => {
5555
});
5656
let isAsyncStorageAvailable = true;
5757

58-
await vi.hoisted(async () => {
59-
await mockRequireNetInfo();
58+
// Mock Node.js module loader to simulate missing @react-native-async-storage/async-storage
59+
vi.hoisted(() => {
60+
mockRequireNetInfo();
6061
});
6162

62-
async function mockRequireNetInfo() {
63-
const { Module } = await import('module');
63+
function mockRequireNetInfo() {
64+
// Dynamically import module synchronously in Node environment
65+
// eslint-disable-next-line @typescript-eslint/no-var-requires
66+
const { Module } = require('module');
6467
const M: any = Module;
6568

6669
M._load_original = M._load;

lib/event_processor/event_processor_factory.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('getBatchEventProcessor', () => {
148148
})).toThrow('Invalid store method getKeys');
149149
});
150150

151-
it.only('returns an instane of BatchEventProcessor if no subclass constructor is provided', () => {
151+
it('returns an instane of BatchEventProcessor if no subclass constructor is provided', () => {
152152
const options = {
153153
eventDispatcher: getMockEventDispatcher(),
154154
defaultFlushInterval: 1000,

lib/logging/logger_factory.spec.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,47 @@
1515
*/
1616
import { describe, it, expect, beforeEach, vi } from 'vitest';
1717

18-
vi.mock('./logger', async (importOriginal) => {
19-
const actual = await importOriginal()
18+
// vi.mock('./logger', async (importOriginal) => {
19+
// const actual = await importOriginal()
2020

21+
// const MockLogger = vi.fn();
22+
// const MockConsoleLogHandler = vi.fn();
23+
24+
// return { ...actual as any, OptimizelyLogger: MockLogger, ConsoleLogHandler: MockConsoleLogHandler };
25+
// });
26+
27+
// vitest does not handle Class mock well when transpiling to ES6 with { spy: true }.
28+
// So we provide a manual mock here.
29+
// also importOriginal() does not work here, so we mock every export of the moddule.
30+
31+
vi.mock('./logger', () => {
2132
const MockLogger = vi.fn();
33+
2234
const MockConsoleLogHandler = vi.fn();
2335

24-
return { ...actual as any, OptimizelyLogger: MockLogger, ConsoleLogHandler: MockConsoleLogHandler };
36+
return {
37+
LogLevel: {
38+
Debug: 0,
39+
Info: 1,
40+
Warn: 2,
41+
Error: 3,
42+
},
43+
LogLevelToUpper: {
44+
0: 'DEBUG',
45+
1: 'INFO',
46+
2: 'WARN',
47+
3: 'ERROR',
48+
},
49+
LogLevelToLower: {
50+
0: 'debug',
51+
1: 'info',
52+
2: 'warn',
53+
3: 'error',
54+
},
55+
OptimizelyLogger: MockLogger,
56+
ConsoleLogHandler: MockConsoleLogHandler,
57+
__platforms: ['__universal__'],
58+
};
2559
});
2660

2761
import { OptimizelyLogger, ConsoleLogHandler, LogLevel } from './logger';
@@ -84,6 +118,8 @@ describe('createLogger', () => {
84118
logHandler: mockLogHandler,
85119
}));
86120

121+
console.log(OptimizelyLogger);
122+
87123
expect(logger).toBe(MockedOptimizelyLogger.mock.instances[0]);
88124
const { name, level, infoMsgResolver, errorMsgResolver, logHandler } = MockedOptimizelyLogger.mock.calls[0][0];
89125
expect(name).toBe('Optimizely');

lib/project_config/config_manager_factory.react_native.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
import { describe, it, expect, beforeEach, vi } from 'vitest';
1818

19-
await vi.hoisted(async () => {
20-
await mockRequireAsyncStorage();
19+
vi.hoisted(async () => {
20+
mockRequireAsyncStorage();
2121
});
2222

2323
let isAsyncStorageAvailable = true;
2424

25-
async function mockRequireAsyncStorage() {
26-
const { Module } = await import('module');
25+
function mockRequireAsyncStorage() {
26+
const { Module } = require('module');
2727
const M: any = Module;
2828

2929
M._load_original = M._load;

lib/project_config/project_config_manager.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ describe('ProjectConfigManagerImpl', () => {
530530
await wait(0);
531531
}
532532

533-
datafileManagerTerminated.reject();
533+
datafileManagerTerminated.reject(new Error('test error'));
534+
534535
await expect(manager.onTerminated()).rejects.toThrow();
535536
expect(manager.getState()).toBe(ServiceState.Failed);
536537
});

lib/project_config/project_config_manager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ export class ProjectConfigManagerImpl extends BaseService implements ProjectConf
227227
}
228228

229229
this.datafileManager.stop();
230+
console.log('stopping datafile manager', this.datafileManager.onTerminated);
231+
230232
this.datafileManager.onTerminated().then(() => {
231233
this.state = ServiceState.Terminated;
232234
this.stopPromise.resolve();

lib/utils/cache/local_storage_cache.browser.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('LocalStorageCache', () => {
7373
const cache = new LocalStorageCache<string>();
7474
cache.set('key1', 'value1');
7575
cache.set('key2', 'value2');
76-
expect(cache.getKeys()).toEqual(['key1', 'key2']);
76+
expect(cache.getKeys().sort()).toEqual(['key1', 'key2']);
7777
});
7878

7979
it('should return an array of values for an array of keys when getBatched is called', () => {

0 commit comments

Comments
 (0)