Skip to content

Fix SauceLabs tests #1920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/karma.saucelabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ module.exports = function(config) {
preprocessors: {
'packages/polyfill/index.ts': ['webpack', 'sourcemap'],
'**/test/**/*.ts': ['webpack', 'sourcemap'],
'**/*.test.ts': ['webpack', 'sourcemap'],
'packages/firestore/test/**/bootstrap.ts': ['webpack', 'babel'],
'integration/**/namespace.*': ['webpack', 'babel', 'sourcemap']
},
Expand Down
22 changes: 21 additions & 1 deletion config/webpack.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ module.exports = {
options: {
compilerOptions: {
module: 'commonjs',
downlevelIteration: true
target: 'es5',
downlevelIteration: true,
resolveJsonModule: true
}
}
}
Expand All @@ -49,11 +51,29 @@ module.exports = {
},
enforce: 'post',
include: path.resolve(process.cwd(), 'src')
},
{
test: /\.js$/,
include: [/node_modules\/chai-as-promised/],
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: ['ie 11']
}
]
]
}
}
}
]
},
resolve: {
modules: ['node_modules', path.resolve(__dirname, '../../node_modules')],
mainFields: ['browser', 'main', 'module'],
extensions: ['.js', '.ts']
},
plugins: [
Expand Down
1 change: 1 addition & 0 deletions integration/shared/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,4 @@ function validateNamespace(definition, candidate) {
}

module.exports = validateNamespace;
module.exports.default = validateNamespace;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"typedoc": "0.15.0",
"ts-node": "8.3.0",
"typescript": "3.5.3",
"yargs": "14.0.0"
"yargs": "14.0.0",
"babel-loader": "8.0.6"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ import { expect } from 'chai';
import '../testing/setup';
import { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';

const TYPED_ARRAY_REPRESENTATION = new TextEncoder().encode('hello world');
const BASE_64_REPRESENTATION = btoa('hello world');
const str = 'hello world';
const TYPED_ARRAY_REPRESENTATION = new Uint8Array(str.length);
Copy link
Member

@Feiyang1 Feiyang1 Jul 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed so it works in IE11 without TextEncoder polyfill, though there still are many tests failing in IE11 (due to indexedDB?). Is installations designed to work in IE11 ? @mmermerkaya

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installations should work in IE11. I have not received any bug reports about it not working in IE11.

for (let i = 0; i < str.length; i++) {
TYPED_ARRAY_REPRESENTATION[i] = str.charCodeAt(i);
}

const BASE_64_REPRESENTATION = btoa(str);

describe('bufferToBase64', () => {
it('returns a base64 representation of a Uint8Array', () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/performance/src/services/api_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ describe('Firebase Performance > api_service', () => {
};

const mockWindow = { ...self };
// hack for IE11. self.hasOwnProperty('performance') returns false in IE11
mockWindow.performance = self.performance;

let api: Api;

Expand Down
128 changes: 80 additions & 48 deletions packages/performance/src/services/remote_config_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { stub, SinonStub, useFakeTimers, SinonFakeTimers } from 'sinon';
import { stub, useFakeTimers, SinonFakeTimers, SinonStub } from 'sinon';
import { expect } from 'chai';
import { SettingsService } from './settings_service';
import { CONFIG_EXPIRY_LOCAL_STORAGE_KEY } from '../constants';
import { setupApi } from './api_service';
import { setupApi, Api } from './api_service';
import * as iidService from './iid_service';
import { getConfig } from './remote_config_service';
import { FirebaseApp } from '@firebase/app-types';
Expand All @@ -41,11 +41,10 @@ describe('Performance Monitoring > remote_config_service', () => {
const APP_ID = '1:23r:web:fewq';
const API_KEY = 'asdfghjk';

let fetchStub: SinonStub<[RequestInfo, RequestInit?], Promise<Response>>;
let storageGetItemStub: SinonStub<[string], string | null>;
let clock: SinonFakeTimers;

setupApi(self);
const ApiInstance = Api.getInstance();

function storageGetItemFakeFactory(
expiry: string,
Expand All @@ -67,17 +66,47 @@ describe('Performance Monitoring > remote_config_service', () => {
settingsService.tracesSamplingRate = 1;
}

beforeEach(() => {
fetchStub = stub(self, 'fetch');
storageGetItemStub = stub(self.localStorage, 'getItem');
// parameterized beforeEach. Should be called at beginning of each test.
function setup(
storageConfig: { expiry: string; config: string },
fetchConfig?: { reject: boolean; value?: Response }
): {
storageGetItemStub: SinonStub<[string], string | null>;
fetchStub: SinonStub<[RequestInfo, RequestInit?], Promise<Response>>;
} {
const fetchStub = stub(self, 'fetch');

if (fetchConfig) {
fetchConfig.reject
? fetchStub.rejects()
: fetchStub.resolves(fetchConfig.value);
}

stub(iidService, 'getAuthTokenPromise').returns(
Promise.resolve(AUTH_TOKEN)
);

clock = useFakeTimers(GLOBAL_CLOCK_NOW);
SettingsService.prototype.firebaseAppInstance = ({
options: { projectId: PROJECT_ID, appId: APP_ID, apiKey: API_KEY }
} as unknown) as FirebaseApp;
});

// we need to stub the entire localStorage, because storage can't be stubbed in Firefox and IE.
// stubbing on self(window) seems to only work the first time (at least in Firefox), the subsequent
// tests will have the same stub. stub.reset() in afterEach doesn't help either. As a result, we stub on ApiInstance.
// https://github.com/sinonjs/sinon/issues/662
const storageStub = stub(ApiInstance, 'localStorage');
const getItemStub: SinonStub<[string], string | null> = stub();

storageStub.value({
getItem: getItemStub.callsFake(
storageGetItemFakeFactory(storageConfig.expiry, storageConfig.config)
),
setItem: () => {}
});

return { storageGetItemStub: getItemStub, fetchStub };
}

afterEach(() => {
resetSettingsService();
Expand All @@ -88,15 +117,14 @@ describe('Performance Monitoring > remote_config_service', () => {
it('gets the config from the local storage if available and valid', async () => {
// After global clock. Config not expired.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895330';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
STRINGIFIED_CONFIG
)
);
const { storageGetItemStub: getItemStub } = setup({
expiry: EXPIRY_LOCAL_STORAGE_VALUE,
config: STRINGIFIED_CONFIG
});

await getConfig(IID);

expect(storageGetItemStub).to.be.called;
expect(getItemStub).to.be.called;
expect(SettingsService.getInstance().loggingEnabled).to.be.true;
expect(SettingsService.getInstance().logEndPointUrl).to.equal(LOG_URL);
expect(SettingsService.getInstance().logSource).to.equal(LOG_SOURCE);
Expand All @@ -111,12 +139,12 @@ describe('Performance Monitoring > remote_config_service', () => {
it('does not call remote config if a valid config is in local storage', async () => {
// After global clock. Config not expired.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895330';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
STRINGIFIED_CONFIG
)
);

const { fetchStub } = setup({
expiry: EXPIRY_LOCAL_STORAGE_VALUE,
config: STRINGIFIED_CONFIG
});

await getConfig(IID);

expect(fetchStub).not.to.be.called;
Expand All @@ -125,16 +153,15 @@ describe('Performance Monitoring > remote_config_service', () => {
it('gets the config from RC if local version is not valid', async () => {
// Expired local config.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895320';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
'not a valid config and should not be used'
)

const { storageGetItemStub: getItemStub } = setup(
{ expiry: EXPIRY_LOCAL_STORAGE_VALUE, config: STRINGIFIED_CONFIG },
{ reject: false, value: new Response(STRINGIFIED_CONFIG) }
);
fetchStub.resolves(new Response(STRINGIFIED_CONFIG));

await getConfig(IID);

expect(storageGetItemStub).to.be.calledOnce;
expect(getItemStub).to.be.calledOnce;
expect(SettingsService.getInstance().loggingEnabled).to.be.true;
expect(SettingsService.getInstance().logEndPointUrl).to.equal(LOG_URL);
expect(SettingsService.getInstance().logSource).to.equal(LOG_SOURCE);
Expand All @@ -149,13 +176,15 @@ describe('Performance Monitoring > remote_config_service', () => {
it('does not change the default config if call to RC fails', async () => {
// Expired local config.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895320';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
'not a valid config and should not be used'
)

setup(
{
expiry: EXPIRY_LOCAL_STORAGE_VALUE,
config: 'not a valid config and should not be used'
},
{ reject: true }
);
fetchStub.rejects();

await getConfig(IID);

expect(SettingsService.getInstance().loggingEnabled).to.equal(false);
Expand All @@ -164,17 +193,19 @@ describe('Performance Monitoring > remote_config_service', () => {
it('uses secondary configs if the response does not have all the fields', async () => {
// Expired local config.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895320';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
'not a valid config and should not be used'
)
);
const STRINGIFIED_PARTIAL_CONFIG = `{"entries":{\
"fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
fetchStub.resolves(new Response(STRINGIFIED_PARTIAL_CONFIG));

setup(
{
expiry: EXPIRY_LOCAL_STORAGE_VALUE,
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response(STRINGIFIED_PARTIAL_CONFIG) }
);

await getConfig(IID);

expect(SettingsService.getInstance().loggingEnabled).to.be.true;
Expand All @@ -183,14 +214,15 @@ describe('Performance Monitoring > remote_config_service', () => {
it('uses secondary configs if the response does not have any fields', async () => {
// Expired local config.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895320';
storageGetItemStub.callsFake(
storageGetItemFakeFactory(
EXPIRY_LOCAL_STORAGE_VALUE,
'not a valid config and should not be used'
)
);
const STRINGIFIED_PARTIAL_CONFIG = '{"state":"NO TEMPLATE"}';
fetchStub.resolves(new Response(STRINGIFIED_PARTIAL_CONFIG));

setup(
{
expiry: EXPIRY_LOCAL_STORAGE_VALUE,
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response(STRINGIFIED_PARTIAL_CONFIG) }
);
await getConfig(IID);

expect(SettingsService.getInstance().loggingEnabled).to.be.true;
Expand Down
2 changes: 2 additions & 0 deletions packages/polyfill/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'core-js/features/array/find';
import 'core-js/features/array/find-index';
import 'core-js/features/array/from';
import 'core-js/features/array/some';
import 'core-js/features/typed-array/iterator';
import 'core-js/features/object/assign';
import 'core-js/features/object/entries';
import 'core-js/features/object/values';
Expand All @@ -35,3 +36,4 @@ import 'core-js/features/symbol';
import 'core-js/features/symbol/iterator';
import 'core-js/features/map';
import 'core-js/features/set';
import 'core-js/features/number/is-integer';
13 changes: 10 additions & 3 deletions packages/util/test/errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,16 @@ describe('FirebaseError', () => {

it('has stack', () => {
const e = ERROR_FACTORY.create('generic-error');
assert.isDefined(e.stack);
// Multi-line match trick - .* does not match \n
assert.match(e.stack!, /FirebaseError[\s\S]/);

// In case of IE11, stack will be set only after error is raised, so we throw the error then test.
// https://docs.microsoft.com/en-us/scripting/javascript/reference/stack-property-error-javascript
try {
throw e;
} catch (error) {
assert.isDefined(error.stack);
// Multi-line match trick - .* does not match \n
assert.match(error.stack, /FirebaseError[\s\S]/);
}
});

it('has function names in stack trace in correct order', () => {
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3079,6 +3079,16 @@ babel-generator@^6.18.0:
source-map "^0.5.7"
trim-right "^1.0.1"

[email protected]:
version "8.0.6"
resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb"
integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==
dependencies:
find-cache-dir "^2.0.0"
loader-utils "^1.0.2"
mkdirp "^0.5.1"
pify "^4.0.1"

babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
Expand Down