diff --git a/src/content/datachannel/basic/js/test.js b/src/content/datachannel/basic/js/test.js new file mode 100644 index 000000000..318d0d078 --- /dev/null +++ b/src/content/datachannel/basic/js/test.js @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should transfer text over data channel': (browser) => { + const path = '/src/content/datachannel/basic/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .click('#startButton') + .expect.element('#sendButton').to.be.enabled.before(50); + browser.expect.element('#dataChannelSend').to.be.enabled.before(50); + + browser.setValue('#dataChannelSend', 'HELLO, WORLD!'); + browser + .click('#sendButton') + .pause(50) + .assert.value('#dataChannelReceive', 'HELLO, WORLD!'); + + browser + .click('#closeButton') + .expect.element('#sendButton').to.not.be.enabled.before(50); + + browser.end(); + } +}; \ No newline at end of file diff --git a/src/content/datachannel/datatransfer/js/test.js b/src/content/datachannel/datatransfer/js/test.js new file mode 100644 index 000000000..2e30d5570 --- /dev/null +++ b/src/content/datachannel/datatransfer/js/test.js @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should transfer data over data channel': (browser) => { + const path = '/src/content/datachannel/datatransfer/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .click('#sendTheData') + .pause(1000) + .assert.value('#receiveProgress', '16777200') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/datachannel/filetransfer/js/test.js b/src/content/datachannel/filetransfer/js/test.js new file mode 100644 index 000000000..71105c9a7 --- /dev/null +++ b/src/content/datachannel/filetransfer/js/test.js @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + +export default { + 'It should transfer a file over a datachannel': (browser) => { + const path = '/src/content/datachannel/filetransfer/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .waitForElementNotVisible('#download', 100, 'File download link is not visible') + .waitForElementVisible('#fileInput', 1000) + .setValue('#fileInput', process.cwd() + '/src/content/devices/multi/images/poster.jpg') + .waitForElementVisible('#download', 10000, 'File download link is visible') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/devices/input-output/js/test.js b/src/content/devices/input-output/js/test.js new file mode 100644 index 000000000..f37b3c684 --- /dev/null +++ b/src/content/devices/input-output/js/test.js @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should have select elements for each media device': (browser) => { + const path = '/src/content/devices/input-output/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .waitForElementVisible('#audioSource option:nth-of-type(1)', 1000, 'Check that there is at least one audio source') + .waitForElementVisible('#audioOutput option:nth-of-type(1)', 1000, 'Check that there is at least one audio output') + .waitForElementVisible('#videoSource option:nth-of-type(1)', 1000, 'Check that there is at least one video source') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/getusermedia/gum/js/test.js b/src/content/getusermedia/gum/js/test.js new file mode 100644 index 000000000..5946b4d85 --- /dev/null +++ b/src/content/getusermedia/gum/js/test.js @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should have a video element': (browser) => { + const path = '/src/content/getusermedia/gum/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .waitForElementVisible('video', 5000) + .waitForClientConnected('video', 5000) + .end(); + } +}; \ No newline at end of file diff --git a/src/content/getusermedia/resolution/js/test.js b/src/content/getusermedia/resolution/js/test.js new file mode 100644 index 000000000..137fa95c2 --- /dev/null +++ b/src/content/getusermedia/resolution/js/test.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should have a video element with specific width': (browser) => { + const path = '/src/content/getusermedia/resolution/index.html'; + const url = 'file://' + process.cwd() + path; + + browser + .url(url) + .click('button#qvga') + .waitForElementVisible('video', 5000) + .waitForClientConnected('video', 5000) + .assert.videoWidth('video', 320, 'Video width is 320 wide.') + .click('button#vga') + .waitForElementVisible('video', 5000) + .waitForClientConnected('video', 5000) + .assert.videoWidth('video', 640, 'Video width is 640 wide.') + .click('button#hd') + .waitForElementVisible('video', 5000) + .waitForClientConnected('video', 5000) + .assert.videoWidth('video', 1280, 'Video width is 1280 wide.') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/peerconnection/audio/js/test.js b/src/content/peerconnection/audio/js/test.js new file mode 100644 index 000000000..65b8c893a --- /dev/null +++ b/src/content/peerconnection/audio/js/test.js @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should play audio remote': (browser) => { + const path = '/src/content/peerconnection/audio/index.html'; + const url = 'file://' + process.cwd() + path; + + // TODO Test all codecs? + browser + .url(url) + .click('#callButton') + .waitForClientConnected('#audio2', 5000, 'Receiving remote audio.') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/peerconnection/dtmf/js/test.js b/src/content/peerconnection/dtmf/js/test.js new file mode 100644 index 000000000..9f0a992da --- /dev/null +++ b/src/content/peerconnection/dtmf/js/test.js @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +export default { + 'It should send DTMF codes': (browser) => { + const path = '/src/content/peerconnection/dtmf/index.html'; + const url = 'file://' + process.cwd() + path; + + // TODO Test all codecs? + browser + .url(url) + .click('#callButton') + .waitForClientConnected('audio', 1000, 'Receiving remote audio.') + .useXpath() + .click('/html/body/div/div[@id=\'dialPad\']/div[1]/button[1]') // 1 + .click('/html/body/div/div[@id=\'dialPad\']/div[3]/button[1]') // 9 + .click('/html/body/div/div[@id=\'dialPad\']/div[3]/button[4]') // # + .click('/html/body/div/div[@id=\'dialPad\']/div[4]/button[1]') // A + .useCss() + .assert.value('input#sentTones', '1 9 # A ') + .click('#hangupButton') + .end(); + } +}; \ No newline at end of file diff --git a/src/content/peerconnection/multiple/js/test.js b/src/content/peerconnection/multiple/js/test.js new file mode 100644 index 000000000..42d45e710 --- /dev/null +++ b/src/content/peerconnection/multiple/js/test.js @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +const webdriver = require('selenium-webdriver'); +const seleniumHelpers = require('webrtc-utilities').seleniumLib; + +test('PeerConnection multiple sample', t => { + const driver = seleniumHelpers.buildDriver(); + const path = '/src/content/peerconnection/multiple/index.html'; + const url = (process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())) + path; + + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('startButton')).click(); + }) + .then(() => { + t.pass('got media'); + return driver.wait(() => driver.findElement(webdriver.By.id('callButton')).isEnabled()); + }) + .then(() => { + driver.findElement(webdriver.By.id('callButton')).click(); + return driver.wait(() => driver.executeScript( + 'return pc1Remote && pc1Remote.iceConnectionState === \'connected\'' + + ' && pc2Remote && pc2Remote.iceConnectionState === \'connected\';'), 30 * 1000); + }) + .then(() => { + t.pass('multiple connections connected'); + return driver.findElement(webdriver.By.id('hangupButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return pc1Local === null && ' + + 'pc2Local === null'), 30 * 1000)) + .then(() => { + t.pass('hangup'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); diff --git a/src/content/peerconnection/munge-sdp/js/test.js b/src/content/peerconnection/munge-sdp/js/test.js new file mode 100644 index 000000000..9e3e325ae --- /dev/null +++ b/src/content/peerconnection/munge-sdp/js/test.js @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +const webdriver = require('selenium-webdriver'); +const seleniumHelpers = require('webrtc-utilities').seleniumLib; + +test('Munge SDP sample', t => { + const driver = seleniumHelpers.buildDriver(); + const path = '/src/content/peerconnection/munge-sdp/index.html'; + const url = (process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())) + path; + + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('getMedia')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return typeof window.localStream !== \'undefined\''))) + .then(() => { + t.pass('got media'); + return driver.findElement(webdriver.By.id('createPeerConnection')).click(); + }) + .then(() => { + return driver.wait(webdriver.until.elementIsVisible(driver.findElement(webdriver.By.id('createOffer')))).click(); + }) + .then(() => { + // Need to wait for createOffer to succeed which takes some time + // on travis. + const script = 'return document.querySelector(\'#local>textarea\').value !== \'\''; + return driver.wait(() => driver.executeScript(script)); + }) + .then(() => driver.findElement(webdriver.By.css('#local>textarea')).getAttribute('value')) + .then(value => { + t.ok(value !== '', 'local SDP is shown in textarea'); + return driver.findElement(webdriver.By.id('setOffer')).click(); + }) + .then(() => driver.findElement(webdriver.By.id('createAnswer')).click()) + .then(() => { + // Need to wait for createAnswer to succeed which takes some time + // on travis. + return driver.wait(() => driver.executeScript( + 'return document.querySelector(\'#remote>textarea\').value !== \'\'')); + }) + .then(() => driver.findElement(webdriver.By.css('#remote>textarea')) + .getAttribute('value')) + .then(value => { + t.ok(value !== '', 'remote SDP is shown in textarea'); + return driver.findElement(webdriver.By.id('setAnswer')).click(); + }) + .then(() => driver.wait(() => driver.executeScript( + 'return remotePeerConnection && ' + + 'remotePeerConnection.iceConnectionState === \'connected\';'), 30 * 1000)) + .then(() => { + t.pass('remotePeerConnection ICE connected'); + // Need to make sure some data has had time to transfer. + return driver.wait(() => driver.executeScript('return typeof dataChannelDataReceived !== \'undefined\';')); + }) + .then(() => driver.executeScript('return dataChannelDataReceived;')) + .then(value => t.ok(value !== '', 'dataChannelDataReceived is not empty.')) + .then(() => { + t.pass('remotePeerConnection ICE connected'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); diff --git a/src/content/peerconnection/pc1/js/test.js b/src/content/peerconnection/pc1/js/test.js new file mode 100644 index 000000000..cd56b5371 --- /dev/null +++ b/src/content/peerconnection/pc1/js/test.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +test('PeerConnection pc1 sample', t => { + const webdriver = require('selenium-webdriver'); + const seleniumHelpers = require('webrtc-utilities').seleniumLib; + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/pc1/index.html'; + const url = (process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())) + path; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('startButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return localStream !== null'), 30 * 1000)) + .then(() => { + t.pass('got media'); + return driver.findElement(webdriver.By.id('callButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript( + 'return pc2 && pc2.iceConnectionState === \'connected\';'), 30 * 1000)) + .then(() => { + t.pass('pc2 ICE connected'); + return driver.findElement(webdriver.By.id('hangupButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return pc1 === null'), 30 * 1000)) + .then(() => { + t.pass('hangup'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); diff --git a/src/content/peerconnection/restart-ice/js/test.js b/src/content/peerconnection/restart-ice/js/test.js new file mode 100644 index 000000000..006ebdfa1 --- /dev/null +++ b/src/content/peerconnection/restart-ice/js/test.js @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +function getTransportIds(stats) { + let localId; + let remoteId; + // TODO: figuring out the currently active candidate pair is tricky cross-browser. + // https://github.com/w3c/webrtc-stats/issues/358 + stats.forEach(report => { + if (report.type === 'candidate-pair' && report.state === 'succeeded' && report.writable) { + localId = report.localCandidateId; + remoteId = report.remoteCandidateId; + } + }); + return localId + ' ' + remoteId; +} + +test('PeerConnection restart ICE sample', t => { + const webdriver = require('selenium-webdriver'); + const seleniumHelpers = require('webrtc-utilities').seleniumLib; + const driver = seleniumHelpers.buildDriver(); + + let firstStats = null; + const path = '/src/content/peerconnection/restart-ice/index.html'; + const url = (process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())) + path; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('startButton')).click(); + }) + .then(() => { + t.pass('got media'); + return driver.wait(() => driver.findElement(webdriver.By.id('callButton')).isEnabled(), 30 * 1000); + }) + .then(() => driver.findElement(webdriver.By.id('callButton')).click()) + .then(() => { + t.pass('Pressed callButton'); + return driver.wait(() => driver.executeScript(() => + window.pc1 && (window.pc1.iceConnectionState === 'completed' || + window.pc1.iceConnectionState === 'connected')), 30 * 1000); + }) + .then(() => { + t.pass('pc1 ICE connected or completed'); + // Query the candidate ID's address. It should change during the + // ICE restart. + return driver.wait(() => driver.findElement(webdriver.By.id('restartButton')).isEnabled(), 30 * 1000); + }) + .then(() => seleniumHelpers.getStats(driver, 'pc1')) + .then(stats => { + firstStats = stats; + // listen for iceconnectionstatechange and store events. + return driver.executeScript(() => { + window.icestates = []; + window.pc1.addEventListener('iceconnectionstatechange', () => + window.icestates.push(window.pc1.iceConnectionState)); + }); + }) + .then(() => driver.findElement(webdriver.By.id('restartButton')).click()) + .then(() => { + t.pass('ICE restart triggered'); + return driver.wait(driver.executeScript(() => { + // Firefox goes back to checking and then to connected. + // Chrome (and presumably Safari) to back to connected and then completed. + // Either way we need to wait for two or more state changes. + return window.icestates.length >= 2; + }), 30 * 1000); + }) + // TODO: remove once https://github.com/w3c/webrtc-stats/issues/358 is resolved. + .then(() => driver.sleep(5000)) + .then(() => seleniumHelpers.getStats(driver, 'pc1')) + .then(newStats => { + const newCandidateIds = getTransportIds(newStats); + const oldRemoteIds = getTransportIds(firstStats); + t.notDeepEqual(oldRemoteIds, 'undefined undefined', 'Candidate Ids found ' + + 'in getStats reports'); + t.notEqual(newCandidateIds, oldRemoteIds, 'Candidate ids changed during ' + + 'ICE restart.'); + }) + .then(() => t.end()) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); diff --git a/src/content/peerconnection/trickle-ice/js/test.js b/src/content/peerconnection/trickle-ice/js/test.js new file mode 100644 index 000000000..4a6c2b67d --- /dev/null +++ b/src/content/peerconnection/trickle-ice/js/test.js @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +const webdriver = require('selenium-webdriver'); +const seleniumHelpers = require('webrtc-utilities').seleniumLib; + +test('Candidate Gathering', t => { + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/trickle-ice/index.html'; + const url = `${process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())}${path}`; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('gather')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return pc === null && candidates.length > 0;'), 30 * 1000)) + .then(() => { + t.pass('got candidates'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); + +// Skipping. webdriver.ActionSequence is not implemented in +// marionette/geckodriver hence we cannot double click the server option +// menu without hacks. +test('Loading server data', {skip: process.env.BROWSER === 'firefox'}, t => { + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/trickle-ice/index.html'; + const url = `${process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())}${path}`; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.css('#servers>option')); + }) + .then(element => new webdriver.ActionSequence(driver).doubleClick(element).perform()) + .then(() => driver.findElement(webdriver.By.id('url')).getAttribute('value')) + .then(value => { + t.ok(value !== '', 'doubleclick loads server data'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); + + +// Disabling on firefox until sendKeys is fixed. +// https://github.com/mozilla/geckodriver/issues/683 +test('Adding a server', {skip: process.env.BROWSER === 'firefox'}, t => { + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/trickle-ice/index.html'; + const url = `${process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())}${path}`; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('url')) + .sendKeys('stun:stun.l.google.com:19302'); + }) + .then(() => { + t.pass('url input worked'); + return driver.findElement(webdriver.By.id('add')).click(); + }) + .then(() => driver.findElement(webdriver.By.css('#servers')) + .getAttribute('length')) + .then(length => { + t.ok(length === '2', 'server added'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); + +test('Removing a server', {skip: process.env.BROWSER === 'firefox'}, t => { + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/trickle-ice/index.html'; + const url = `${process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())}${path}`; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.css('#servers>option')).click(); + }) + .then(() => driver.findElement(webdriver.By.id('remove')).click()) + .then(() => driver.findElement(webdriver.By.css('#servers')) + .getAttribute('length')) + .then(length => { + t.ok(length === '0', 'server removed'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +}); diff --git a/src/content/peerconnection/upgrade/js/test.js b/src/content/peerconnection/upgrade/js/test.js new file mode 100644 index 000000000..1a79c68bf --- /dev/null +++ b/src/content/peerconnection/upgrade/js/test.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ +/* eslint-env node */ + +'use strict'; +// This is a basic test file for use with testling. +// The test script language comes from tape. +const test = require('tape'); + +test('PeerConnection upgrade sample', t => { + const webdriver = require('selenium-webdriver'); + const seleniumHelpers = require('webrtc-utilities').seleniumLib; + const driver = seleniumHelpers.buildDriver(); + + const path = '/src/content/peerconnection/upgrade/index.html'; + const url = `${process.env.BASEURL ? process.env.BASEURL : ('file://' + process.cwd())}${path}`; + driver.get(url) + .then(() => { + t.pass('page loaded'); + return driver.findElement(webdriver.By.id('startButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return localStream !== null'), 30 * 1000)) + .then(() => { + t.pass('got media'); + return driver.findElement(webdriver.By.id('callButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return pc2 && pc2.iceConnectionState === \'connected\';'), + 30 * 1000)) + .then(() => { + t.pass('pc2 ICE connected'); + return driver.findElement(webdriver.By.id('upgradeButton')).click(); + }) + .then(() => driver.wait(() => driver.executeScript('return remoteVideo.videoWidth === 640;'), 30 * 1000)) + .then(() => driver.findElement(webdriver.By.id('hangupButton')).click()) + .then(() => driver.wait(() => driver.executeScript('return pc1 === null'), 30 * 1000)) + .then(() => { + t.pass('hangup'); + t.end(); + }) + .then(null, err => { + t.fail(err); + t.end(); + }); +});