Skip to content

Commit dde3bfd

Browse files
author
Kai Wu
committed
Enable the FCM integration test (IT) for Chrome.
Context: the tests were switched off a couple of years ago due to flakiness. It has not been maintained since then. During the time, Some Selenium API methods used were deprecated and removed; the Firebase projects used are no longer managed or owned by the FCM team. Consequently, the test became unfunctional. In the effort of providing safety for the upcoming FCM releases, this PR is created to fix, deflake, refactor and improve the old tests. This PR did the following: - Enabled comprehensive IT for chrome (ver.80). Now we are covering send&foreground recevie for FCM messages (messages with {notification} payload, {data} payload and {notification, data} payload), delete/update token, use default/customized ServiceWorker. - Defalaked test. The IT is now reasonably stable without retry. Previously we are retrying 1 or 3 times. - Optimized test. Previously we create a webDriver for each test, which is slow and annoying. Because a window is created and brought to focus and killed frequently, it makes working on other tasks and testing nearly impossible (Probably using a headless browser would work but I haven't found a satisfying solution to have the app in the state of foreground and background which is a requirement for FCM functions). With the way the tests are organized, the IT only spin up a new web driver when necessary. Some data on performance: (old) 'test-send' take 74 seconds (only measured 'test-send' because the other test suites were not functional at the time); (now) 'test-send', 'test-deleteToken', 'test-updateToken', 'test-useDefaultServiceWorker', 'test-useValidManifest' takes in total 33s (10 run average). - General refactoring. Including refactors on expect blocks, createWebDriver, use const for constants usage, etc. The code should be much easier to understand and maintain. Future work: - Enable test on firefox once I get the notification permission working. - Run the IC against some milestone chrome/firefox version (if it makes sense) to ensure backward compatibility. We should try to avoid #2712 . :)
1 parent 705e9f9 commit dde3bfd

33 files changed

+508
-726
lines changed

integration/messaging/download-browsers.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,9 @@
1818
const seleniumAssistant = require('selenium-assistant');
1919

2020
console.log('Starting browser download - this may take some time.');
21-
Promise.all([
22-
seleniumAssistant.downloadLocalBrowser('chrome', 'stable', 48),
23-
seleniumAssistant.downloadLocalBrowser('chrome', 'beta', 48),
24-
seleniumAssistant.downloadLocalBrowser('chrome', 'unstable', 48),
25-
seleniumAssistant.downloadLocalBrowser('firefox', 'stable', 48),
26-
seleniumAssistant.downloadLocalBrowser('firefox', 'beta', 48),
27-
seleniumAssistant.downloadLocalBrowser('firefox', 'unstable', 48)
28-
])
21+
// TODO: enable firefox testing once figure out how to give notification permission with SE webdriver.
22+
// TODO: Run the integration test against multiple major chrome versions to ensure backward compatibility
23+
Promise.all([seleniumAssistant.downloadLocalBrowser('chrome', 'stable', 80)])
2924
.then(() => {
3025
console.log('Browser download complete.');
3126
})

integration/messaging/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"version": "0.2.1",
55
"scripts": {
66
"pretest:manual": "node ./download-browsers.js",
7-
"test": "echo 'Tests disabled due to flakiness'",
7+
"test": "mocha --exit",
88
"test:manual": "mocha --exit"
99
},
1010
"dependencies": {

integration/messaging/test/static/app.js

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
const EIGHT_DAYS_IN_MS = 8 * 86400000;
19-
2018
/**
2119
* This class just wraps the expected behavior or a demo app that will
2220
* be orchestrated by selenium tests (Although manual use of the demo will
@@ -36,40 +34,45 @@ class DemoApp {
3634
this._triggerDeleteToken = this.triggerDeleteToken;
3735
this._triggerGetToken = this.triggerGetToken;
3836
this._triggerTimeForward = this.triggerTimeForward;
37+
this._clearInstanceForTest = this.clearInstanceForTest;
3938

4039
// Initialize Firebase
4140
firebase.initializeApp(firebaseConfig);
4241

4342
this._messaging = firebase.messaging();
4443

45-
if (options.applicationKey) {
46-
this._messaging.usePublicVapidKey(options.applicationKey);
44+
if (options.vapidKey) {
45+
console.debug('VapidKey is provided to the test app. ');
46+
this._messaging.usePublicVapidKey(options.vapidKey);
47+
} else {
48+
console.debug('VapidKey is not specified. Skip setting it');
4749
}
4850

4951
if (options.swReg) {
52+
console.debug('ServiceWorker is provided to the test app');
5053
this._messaging.useServiceWorker(options.swReg);
54+
} else {
55+
console.debug(
56+
'ServiceWorker is not specified. The default ServiceWorker will be used.'
57+
);
5158
}
5259

5360
this._messaging.onMessage(payload => {
5461
console.log(`Message received: `, payload);
5562
this._messages.push(payload);
5663
});
5764

58-
// Initializa state of token
59-
this._messaging
60-
.requestPermission()
61-
.then(() => this._messaging.getToken())
62-
.then(
63-
token => {
64-
console.log('getToken() worked: ', token);
65-
this._token = token;
66-
},
67-
err => {
68-
console.log('getToken() failed: ', err.message, err.stack);
69-
this._errors.push(err);
70-
this._token = null;
71-
}
72-
);
65+
this._messaging.getToken().then(
66+
token => {
67+
console.log('Test app getToken() succeed. Token: ', token);
68+
this._token = token;
69+
},
70+
err => {
71+
console.log('Test app getToken() failed: ', err.message, err.stack);
72+
this._errors.push(err);
73+
this._token = null;
74+
}
75+
);
7376
}
7477

7578
async triggerDeleteToken(token) {
@@ -99,6 +102,11 @@ class DemoApp {
99102
this._clock.tick(EIGHT_DAYS_IN_MS);
100103
}
101104

105+
async clearInstanceForTest() {
106+
this._errors = [];
107+
this._messages = [];
108+
}
109+
102110
get token() {
103111
return this._token;
104112
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const EIGHT_DAYS_IN_MS = 8 * 86400000;
2+
const PUBLIC_VAPID_KEY =
3+
'BAN_2QvaSnxnjz-2y1sARN1ErEpZhcb8kaSI08pLxiAtQPB4ja3wg_1T0cGBMpt-vRd_6G1LZeVcVYlQeSPlbt8';
Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
<html>
2-
<head>
3-
<title>FCM Demo</title>
4-
<meta name="viewport" content="width=device-width,initial-scale=1">
5-
</head>
6-
<body>
7-
<h1>Default SW</h1>
8-
<script src="/firebase/firebase-app.js"></script>
9-
<script src="/firebase/firebase-messaging.js"></script>
10-
<script src="/app.js"></script>
11-
<script src="../valid-no-vapid-key/firebaseConfig.js"></script>
12-
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/4.1.3/sinon.min.js"></script>
13-
<script>
14-
window.__test = new window.DemoApp(window.firebaseConfig);
15-
</script>
16-
</body>
17-
</html>
2+
<head>
3+
<title>FCM Demo</title>
4+
<meta name="viewport" content="width=device-width,initial-scale=1" />
5+
</head>
6+
<body>
7+
<h1>Default SW</h1>
8+
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-app.js"></script>
9+
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-messaging.js"></script>
10+
<script src="/app.js"></script>
11+
<script src="/firebaseConfig.js"></script>
12+
<script src="/constants.js"></script>
13+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/4.1.3/sinon.min.js"></script>
14+
<script>
15+
window.__test = new window.DemoApp(FIREBASE_CONFIG, {
16+
vapidKey: PUBLIC_VAPID_KEY
17+
});
18+
</script>
19+
</body>
20+
</html>

integration/messaging/test/static/firebase-messaging-sw.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,38 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
importScripts('https://www.gstatic.com/firebasejs/7.10.0/firebase-app.js');
18+
importScripts(
19+
'https://www.gstatic.com/firebasejs/7.10.0/firebase-messaging.js'
20+
);
21+
importScripts('/firebaseConfig.js');
22+
firebase.initializeApp(FIREBASE_CONFIG);
1723

18-
importScripts('/sw-shared.js');
19-
importScripts('/valid-no-vapid-key/firebaseConfig.js');
24+
const messaging = firebase.messaging();
2025

21-
firebase.initializeApp(self.firebaseConfig);
26+
messaging.setBackgroundMessageHandler(payload => {
27+
console.log(
28+
'Received a background message: ' +
29+
JSON.stringify(payload) +
30+
'. Routing the message to the test app messages container to be read'
31+
);
2232

23-
const messaging = firebase.messaging();
24-
messaging.setBackgroundMessageHandler(data => {
25-
const title = 'Background Notification';
26-
return self.registration.showNotification(title, {});
33+
sendMessageToWindowClients(getClients(), markBackgroundMessage(payload));
2734
});
35+
36+
function getClients() {
37+
return self.clients.matchAll({
38+
type: 'window',
39+
includeUncontrolled: true
40+
});
41+
}
42+
43+
function sendMessageToWindowClients(clientList, payload) {
44+
for (const client of clientList) {
45+
client.postMessage({ ...message, 'isBackgroundMessage': true });
46+
}
47+
}
48+
49+
function markBackgroundMessage(payload) {
50+
return { ...payload, 'isBackgroundMessage': true };
51+
}

integration/messaging/test/static/valid-vapid-key/firebaseConfig.js renamed to integration/messaging/test/static/firebaseConfig.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@
1515
* limitations under the License.
1616
*/
1717

18-
const config = {
19-
apiKey: 'AIzaSyCaSnFca0oG_b-t-s_p9wRdr9o9aSPmolE',
20-
authDomain: 'fcm-sdk-testing-vapid-key.firebaseapp.com',
21-
databaseURL: 'https://fcm-sdk-testing-vapid-key.firebaseio.com',
22-
projectId: 'fcm-sdk-testing-vapid-key',
23-
storageBucket: '',
24-
messagingSenderId: '650229866790'
18+
const FIREBASE_CONFIG = {
19+
apiKey: 'AIzaSyBVqFz5vuknTmaVJyRnjxSolqhc8hXx0M4',
20+
authDomain: 'android-gcm-test-519bd.firebaseapp.com',
21+
databaseURL: 'https://android-gcm-test-519bd.firebaseio.com',
22+
projectId: 'android-gcm-test-519bd',
23+
storageBucket: 'android-gcm-test-519bd.appspot.com',
24+
messagingSenderId: '35006771263',
25+
appId: '1:35006771263:web:18cc19582bf589e8c9c88a'
2526
};
2627

2728
if (this['window']) {
28-
window.firebaseConfig = config;
29+
window.firebaseConfig = FIREBASE_CONFIG;
2930
} else if (this['module']) {
30-
module.exports = config;
31+
module.exports = FIREBASE_CONFIG;
3132
} else {
32-
self.firebaseConfig = config;
33+
self.firebaseConfig = FIREBASE_CONFIG;
3334
}

integration/messaging/test/static/invalid-manifest/index.html

Lines changed: 0 additions & 18 deletions
This file was deleted.

integration/messaging/test/static/invalid-manifest/manifest.json

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
<html>
2-
<head>
3-
<title>FCM Demo</title>
4-
<link rel="manifest" href="./manifest.json">
5-
<meta name="viewport" content="width=device-width,initial-scale=1">
6-
</head>
7-
<body>
8-
<h1>Valid Manifest</h1>
9-
<script src="/firebase/firebase-app.js"></script>
10-
<script src="/firebase/firebase-messaging.js"></script>
11-
<script src="/app.js"></script>
12-
<script src="../valid-no-vapid-key/firebaseConfig.js"></script>
13-
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/4.1.3/sinon.min.js"></script>
14-
<script>
15-
window.__test = new window.DemoApp(window.firebaseConfig);
16-
</script>
17-
</body>
18-
</html>
2+
<head>
3+
<title>FCM Demo</title>
4+
<link rel="manifest" href="./manifest.json" />
5+
<meta name="viewport" content="width=device-width,initial-scale=1" />
6+
</head>
7+
<body>
8+
<h1>Valid Manifest</h1>
9+
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-app.js"></script>
10+
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-messaging.js"></script>
11+
<script src="/app.js"></script>
12+
<script src="/firebaseConfig.js"></script>
13+
<script src="/constants.js"></script>
14+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/4.1.3/sinon.min.js"></script>
15+
<script>
16+
window.__test = new window.DemoApp(window.firebaseConfig, {});
17+
</script>
18+
</body>
19+
</html>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"gcm_sender_id": "103953800507"
2+
"gcm_sender_id": "35006771263"
33
}

integration/messaging/test/static/valid-no-vapid-key/firebaseConfig.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

integration/messaging/test/static/valid-no-vapid-key/index.html

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)