How to use longSleep method in Appium Android Driver

Best JavaScript code snippet using appium-android-driver

kwm.js

Source:kwm.js Github

copy

Full Screen

1import { defineMessages } from 'react-intl';2import { setError, enqueueErrorSnackbar, enqueueSnackbar, closeSnackbar } from 'kpop/es/common/actions';3import * as kwmjs from 'kwmjs';4import adapter from 'webrtc-adapter';5import * as types from './types';6import * as errors from '../errors';7import * as sdputils from '../sdputils';8import { fetchAndUpdateContactByID } from './contacts';9import { resolveContactIDFromRecord } from '../utils';10import { guestLogon } from '../api/kwm';11console.info(`Kopano KWM js version: ${kwmjs.version}`); // eslint-disable-line no-console12const defaultAudioVideoSdpParams = {13 videoRecvCodec: 'VP8', // Prefer VP8 since it takes less CPU?14 videoSendBitrate: 1000, // kbps15 videoRecvBitrate: 1000, // kbps16};17const defaultAudioVideoLocalParams = {18 opusDtx: true,19 opusFec: true,20 opusMaxPbr: 48000, // nb: 8, mb: 12, wb: 16, swb: 24, fb: 48 (all kHz)21};22const defaultAudioVideoRemoteParams = {};23const defaultScreenhareSdpParams = {24 videoRecvCodec: 'VP9', // Prefer VP9 since its more modern and gives better results for screen sharing.25 videoSendBitrate: 2500, // kbps26 videoRecvBitrate: 2500, // kbps27};28// Fixup webrtc-adpter for Firefox to be compatible with kwmjs simple-peer poor feature detection.29// See https://github.com/feross/simple-peer/commits/master/index.js and ensure it ends up to detect promise based shit.30(() => {31 if (adapter.browserDetails.browser === 'firefox') {32 // Ensure that function signature of getStats has zero parameters, so that33 // the feature detection of kwmks simple-peer does select the promise based34 // mode.35 if (window.RTCPeerConnection.prototype.getStats.length > 0) {36 const adaptedGetStats = window.RTCPeerConnection.prototype.getStats;37 window.RTCPeerConnection.prototype.getStats = function() {38 return adaptedGetStats.apply(this);39 };40 }41 }42})();43// Reference to the active KWM and options.44let kwm = null;45const kwmOptions = {46 id: null,47 user: null,48 userMode: 'id_token',49 options: {},50};51// KWM config.52const kwmConfig = (() => {53 const config ={54 url: '',55 webrtc: {},56 sdpParams: {},57 };58 return config;59})();60const translations = defineMessages({61 kwmError: {62 id: 'kwm.errorMessage.kwmError.message',63 defaultMessage: 'Error: KWM error - {msg} {code}',64 },65});66// Default WebRTC constraints.67const defaultCommonConstraints = (() => {68 const constraints = {};69 if (adapter.browserDetails.browser === 'chrome') {70 // Add Google specific constraints.71 Object.assign(constraints, {72 googIPv6: true, // Constraint to enable IPv6 through JS.73 googDscp: true, // Temporary pseudo-constraint for enabling DSCP through JS.74 // Google specific constraints.75 googCpuOveruseDetection: true,76 googCpuOveruseEncodeUsage: true,77 googCpuUnderuseThreshold: 55,78 googCpuOveruseThreshold: 85,79 googHighStartBitrate: 0,80 googPayloadPadding: true,81 googSuspendBelowMinBitrate: true,82 googScreencastMinBitrate: 400,83 });84 }85 return constraints;86})();87// WebRTC confg.88const webrtcConfig = (() => {89 const config = {90 iceServers: [91 {urls: 'stun:stun.kopano.com:443'},92 ],93 iceTransportPolicy: 'all', // Either 'all' or 'relay' to force going through relay.94 };95 if (adapter.browserDetails.browser === 'chrome') {96 // For interoperability with Firefox and others, we need to send standard sdp. This sets the plan to unified plan97 // effectively breaking compatibilty with Chromeium < M69. See https://webrtc.org/web-apis/chrome/unified-plan/.98 config.sdpSemantics = 'unified-plan';99 }100 return config;101})();102// WebRTC options.103const webrtcOptions = {104 answerConstraints: {105 ...defaultCommonConstraints,106 },107 offerConstraints: {108 ...defaultCommonConstraints,109 },110};111// SDP Config.112const sdpParamsAudioVideo = {113 ...defaultAudioVideoSdpParams,114};115const sdpParamsScreenshare = {116 ...defaultScreenhareSdpParams,117};118export function setupKWM(id, idToken, {authorizationType, authorizationValue, autoConnect, eventCallback} = {}) {119 return async (dispatch, getState) => {120 const { config } = getState().common;121 if (id !== kwmOptions.id) {122 // Always disconnect when the user changed.123 await dispatch(disconnectFromKWM());124 }125 // Update KWM options by reference.126 kwmOptions.id = id; // eslint-disable-line require-atomic-updates127 kwmOptions.user = idToken; // eslint-disable-line require-atomic-updates128 Object.assign(kwmOptions.options, {129 authorizationType,130 authorizationValue,131 authorizationAuth: config.useIdentifiedUser ? '1' : '', // Use auth 1 to use real user identity.132 });133 // Auto connect support when requested.134 if (autoConnect) {135 if (kwm && kwm.connected) {136 return kwm;137 }138 return dispatch(connectToKWM(idToken, eventCallback));139 }140 return kwm;141 };142}143export function destroyKWM() {144 return async (dispatch) => {145 if (kwm) {146 await dispatch(disconnectFromKWM());147 kwm = null; // eslint-disable-line require-atomic-updates148 }149 };150}151function connectToKWM(user, eventCallback) {152 return async (dispatch) => {153 if (!user || kwmOptions.user !== user) {154 throw new Error('invalid user set for KWM connect');155 }156 if (!kwmOptions.options.authorizationType) {157 throw new Error('no user or options set for KWM connect');158 }159 if (kwm === null) {160 kwm = await dispatch(createKWMManager(eventCallback)); // eslint-disable-line require-atomic-updates161 }162 await kwm.connect(user, kwmOptions.userMode);163 return kwm;164 };165}166function disconnectFromKWM() {167 return async () => {168 if (kwm) {169 try {170 await kwm.destroy();171 } catch(err) {172 console.error('disconnect destroy failed with error', err); // eslint-disable-line no-console173 }174 }175 kwmOptions.id = null;176 kwmOptions.user = null;177 delete kwmOptions.options.authorizationType;178 delete kwmOptions.options.authorizationValue;179 };180}181function createKWMManager(eventCallback) {182 return async (dispatch, getState) => {183 const { config } = getState().common;184 const { mode } = getState().meet;185 if (!config.kwm) {186 throw new Error('config is missing KWM configuration data');187 }188 // Update defaults from configuration.189 Object.assign(kwmConfig, config.kwm);190 Object.assign(webrtcConfig, kwmConfig.webrtc.config);191 Object.assign(webrtcOptions, kwmConfig.webrtc.options);192 Object.assign(sdpParamsAudioVideo, kwmConfig.sdpParams);193 Object.assign(sdpParamsScreenshare, kwmConfig.sdpParamsScreenshare);194 kwmjs.KWMInit.init({}); // Init with default options.195 const k = new kwmjs.KWM(kwmConfig.url, kwmOptions.options);196 k.webrtc.config = {197 ...webrtcConfig,198 };199 k.webrtc.options = {200 ...webrtcOptions,201 localSDPTransform: (sdp, kind='') => {202 const { settings } = getState().media;203 let sdpParams;204 switch (kind) {205 case 'screenshare':206 sdpParams = sdpParamsScreenshare;207 break;208 default:209 sdpParams = sdpParamsAudioVideo;210 break;211 }212 // Local SDP transform support.213 const params = Object.assign({214 ...defaultAudioVideoLocalParams,215 }, sdpParams, {216 // TODO(longsleep): Add configuration settings here.217 opusStereo: true, // Tell the receiver to decode stereo.218 opusSpropStereo: settings.audio.channelCount === 2,219 });220 sdp = sdputils.maybeSetOpusOptions(sdp, params);221 sdp = sdputils.maybePreferAudioReceiveCodec(sdp, params);222 sdp = sdputils.maybePreferVideoReceiveCodec(sdp, params);223 sdp = sdputils.maybeSetAudioReceiveBitRate(sdp, params);224 sdp = sdputils.maybeSetVideoReceiveBitRate(sdp, params);225 sdp = sdputils.maybeRemoveVideoFec(sdp, params);226 return sdp;227 },228 remoteSDPTransform: (sdp, kind='') => {229 let sdpParams;230 switch (kind) {231 case 'screenshare':232 sdpParams = sdpParamsScreenshare;233 break;234 default:235 sdpParams = sdpParamsAudioVideo;236 break;237 }238 // Remote SDP transform support.239 const params = Object.assign({240 ...defaultAudioVideoRemoteParams,241 }, sdpParams, {242 // TODO(longsleep): Add configuration settings here.243 });244 sdp = sdputils.maybeSetOpusOptions(sdp, params);245 sdp = sdputils.maybePreferAudioSendCodec(sdp, params);246 sdp = sdputils.maybePreferVideoSendCodec(sdp, params);247 sdp = sdputils.maybeSetAudioSendBitRate(sdp, params);248 sdp = sdputils.maybeSetVideoSendBitRate(sdp, params);249 sdp = sdputils.maybeSetVideoSendInitialBitRate(sdp, params);250 sdp = sdputils.maybeRemoveVideoFec(sdp, params);251 return sdp;252 },253 transceiverRequestTransform: (transceiverRequest) => {254 if (transceiverRequest && transceiverRequest.kind === 'video') {255 const { mode } = getState().meet;256 if (mode === 'call') {257 // Do not create receiver for video track if in call mode. This258 // is the way how receiving of unwanted streams is prevented if we259 // are the offerer.260 return null;261 }262 }263 return transceiverRequest;264 },265 onRemoteDescriptionSet: (owner, pc) => {266 if (pc.remoteDescription.type === 'offer') {267 // If remote is the offerer, we can further control incoming transceivers268 // base based on our local state, before we send back the answer.269 const { mode } = getState().meet;270 // Do not accept video receiversx if in call mode.271 pc.getTransceivers().forEach(transceiver => {272 if (transceiver.receiver && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {273 if (mode === 'call') {274 transceiver.direction = 'inactive';275 } else if (transceiver.direction === 'inactive') {276 // Resurrect, to be able to receive again.277 transceiver.direction = 'sendrecv';278 }279 }280 });281 }282 },283 };284 console.info('KWM init', kwmConfig, webrtcConfig, webrtcOptions, sdpParamsAudioVideo, sdpParamsScreenshare); // eslint-disable-line no-console285 let connected = undefined;286 k.onstatechanged = event => {287 if (event.target !== kwm) {288 return;289 }290 if (event.connected) {291 // Ensure that all existing pc connections do a renegotiation dance after292 // kwm server connection to ensure server state is correct.293 kwm.webrtc.peers.forEach(record => {294 if (record.pc) {295 record.pc._needsNegotiation();296 }297 });298 }299 if (connected === undefined) {300 connected = event.connected;301 if (!event.connected) {302 // NOTE(longsleep): Ignore initial unconnected state.303 return;304 }305 }306 dispatch(stateChanged(event));307 };308 k.onserverstatus = event => {309 if (event.target !== kwm) {310 return;311 }312 console.info('KWM server status update', event.serverStatus); // eslint-disable-line no-console313 dispatch(serverStatus(event));314 };315 k.onerror = event => {316 if (event.target !== kwm) {317 return;318 }319 dispatch(error(event));320 };321 k.onturnserverchanged = event => {322 console.info('KWM using TURN servers', event.iceServer.urls); // eslint-disable-line no-console323 };324 k.webrtc.onpeer = event => {325 if (!kwm || event.target !== kwm.webrtc) {326 return;327 }328 switch (event.event) {329 case 'newcall':330 dispatch(newCall(event));331 break;332 case 'destroycall':333 dispatch(destroyAndHangupCall(event));334 break;335 case 'abortcall':336 dispatch(abortAndHangupCall(event));337 break;338 case 'incomingcall':339 dispatch(incomingCall(event));340 break;341 case 'outgoingcall':342 dispatch(outgoingCall(event));343 break;344 case 'pc.connect':345 dispatch(pcConnect(event));346 break;347 case 'pc.closed':348 dispatch(pcClosed(event));349 break;350 case 'pc.iceStateChange':351 // TODO(longsleep): Implement iceRestart.352 // See https://github.com/w3c/webrtc-pc/pull/1910#issuecomment-398986406353 // and https://w3c.github.io/webrtc-pc/#dom-rtcofferoptions-icerestart.354 break;355 // Reduce logging.356 case 'pc.new':357 case 'pc.signalingStateChange':358 case 'pc.error':359 case 'hangup':360 //console.debug(`KWM event ${event.event}`, event.details, event.record);361 break;362 // Catch unknowns.363 default:364 console.warn('KWM unknown peer event', event.event, event); // eslint-disable-line no-console365 break;366 }367 // Cleanup if no peers are left.368 if (event.target.peers.size === 0) {369 if (event.target.channel !== '' && !event.target.group) {370 console.log('KWM hangup as no peers are left'); // eslint-disable-line no-console371 dispatch(doHangup());372 } else if (event.target.channel === '') {373 // Reset channel when not having a channel and no peers.374 dispatch(resetChannel());375 }376 }377 if (eventCallback) {378 eventCallback(event);379 }380 };381 k.webrtc.onannouncestreams = event => {382 if (!kwm || event.target !== kwm.webrtc) {383 return;384 }385 dispatch(streamsAnnounce(event));386 };387 k.webrtc.ontrack = event => {388 if (!kwm || event.target !== kwm.webrtc) {389 return;390 }391 dispatch(streamReceived(event));392 };393 k.chats.onmessage = event => {394 if (!kwm || event.target !== kwm.chats) {395 return;396 }397 // Ensure to let through only message kinds we know about.398 const { message } = event;399 switch (message.kind) {400 case '':401 break;402 default:403 console.warn('unknown chats message kind received', message.kind); // eslint-disable-line no-console404 return;405 }406 dispatch(chatsMessageReceived(event));407 };408 k.chats.onsystem = event => {409 if (!kwm || event.target !== kwm.chats) {410 return;411 }412 dispatch(chatsSystemReceived(event));413 };414 k.webrtc.setMode(mode);415 return k;416 };417}418function error(event) {419 return async (dispatch) => {420 let fatal = true;421 switch (event.code) {422 case 'no_session_for_user':423 // NOTE(longsleep): This error is pretty useless as it does not return424 // enough information to know which call actually is meant here.425 console.debug('KMW error ignored', event.code, event); // eslint-disable-line no-console426 return;427 case 'http_error_403':428 // NOTE(longsleep): For whatever reason we were not allowed to429 // connect KWM. Do something useful instead of just bailing430 // with the error since this can happen when the access token431 // is expired (like after a device resume).432 dispatch(doHangup());433 await setNonFatalError(errors.ERROR_KWM_NO_PERMISSION, event);434 return;435 case 'websocket_error':436 // NOTE(longsleep): We ignore websocket errors here. KWM will automatically437 // reconnect.438 console.debug('KWM error ignored', event.code, event); // eslint-disable-line no-console439 return;440 default:441 }442 console.warn('KWM error event', event.code, event); // eslint-disable-line no-console443 // TODO(longsleep): Make only fatal if kwm is not reconnecting.444 const error = {445 message: translations.kwmError,446 fatal: fatal,447 values: {448 msg: event.msg,449 code: event.code,450 },451 };452 dispatch(doHangup());453 await dispatch(setError(error));454 };455}456function stateChanged(event) {457 return (dispatch, getState) => {458 const { connected: oldConnected } = getState().kwm;459 const { connecting, connected, reconnecting } = event;460 if (oldConnected !== connected) {461 if (!connected && kwmOptions.id) {462 const error = {463 fatal: false,464 options: {465 key: 'kwm_statechanged_not_connected',466 persist: true,467 },468 };469 error.message = oldConnected ? 'Lost connection to server - check your Internet connection.' : 'Failed to connect to server - check your Internet connection.';470 dispatch(closeSnackbar('kwm_statechanged_connected'));471 dispatch(enqueueErrorSnackbar(error));472 } else if (oldConnected === false) {473 const notification = {474 message: 'Server connection reestablished.',475 options: {476 key: 'kwm_statechanged_connected',477 variant: 'success',478 },479 };480 dispatch(closeSnackbar('kwm_statechanged_not_connected'));481 dispatch(enqueueSnackbar(notification));482 }483 }484 return dispatch({485 type: types.KWM_STATE_CHANGED,486 connecting,487 connected,488 reconnecting,489 });490 };491}492function serverStatus(event) {493 return (dispatch, getState) => {494 const { serverStatus } = event;495 dispatch( {496 type: types.KWM_SERVERSTATUS_CHANGED,497 serverStatus,498 });499 };500}501function channelChanged(channel) {502 return {503 type: types.KWM_CHANNEL_CHANGED,504 channel,505 };506}507function incomingCall(event, doneHandler = null) {508 const { record } = event;509 return {510 type: types.KWM_CALL_INCOMING,511 record,512 doneHandler,513 };514}515function outgoingCall(event, doneHandler = null) {516 const { record } = event;517 return {518 type: types.KWM_CALL_OUTGOING,519 record,520 doneHandler,521 };522}523function newCall(event) {524 const { record } = event;525 return async (dispatch, getState) => {526 const state = getState();527 const { table } = state.contacts;528 const { config } = state.common;529 const id = resolveContactIDFromRecord(config, event.record);530 let entry = table[id];531 if (!entry) {532 console.warn('unknown user for call', event.record.user); // eslint-disable-line no-console533 entry = {534 // TODO(longsleep): Find some way to describe unknown users.535 displayName: '',536 };537 // Try to fetch contact data via api.538 dispatch(fetchAndUpdateContactByID(id)).catch(err => {539 console.warn('failed to fetch and update contact' + // eslint-disable-line no-console540 ' information for new call', err);541 });542 }543 // Copy to retain reference.544 const user = {displayName: entry.displayName};545 return dispatch({546 type: types.KWM_CALL_NEW,547 record,548 user,549 });550 };551}552function destroyCall(event) {553 const { record } = event;554 // TODO(longsleep): Reconnect instead of hangup?555 if (kwm.webrtc.peers.get(record.user)) {556 kwm.webrtc.doHangup(record.user);557 }558 return {559 type: types.KWM_CALL_DESTROY,560 record,561 };562}563function pcConnect(event) {564 const { record, details: pc } = event;565 return {566 type: types.KWM_PC_CONNECT,567 record,568 pc,569 };570}571function pcClosed(event) {572 const { record, details: pc } = event;573 return {574 type: types.KWM_PC_CLOSED,575 record,576 pc,577 };578}579function destroyAndHangupCall(event) {580 const { record } = event;581 return async dispatch => {582 dispatch(destroyCall(event));583 if (kwm.webrtc.peers.get(record.user)) {584 await kwm.webrtc.doHangup(record.user);585 }586 };587}588function abortCall(event) {589 const { record, details } = event;590 return {591 type: types.KWM_CALL_ABORT,592 record,593 details,594 };595}596function abortAndHangupCall(event) {597 const { record } = event;598 return async dispatch => {599 dispatch(abortCall(event));600 if (kwm.webrtc.peers.get(record.user)) {601 await kwm.webrtc.doHangup(record.user);602 }603 };604}605function streamReceived(event) {606 const { record, stream, token } = event;607 return {608 type: types.KWM_STREAM_RECEIVED,609 record,610 stream,611 token,612 };613}614function streamsAnnounce(event) {615 const { record, added, removed } = event;616 return {617 type: types.KWM_STREAMS_ANNOUNCE,618 record,619 added,620 removed,621 };622}623function resetChannel() {624 return async (dispatch, getState) => {625 const { channel } = getState().kwm;626 if (channel) {627 await dispatch(channelChanged(null));628 }629 };630}631function setNonFatalError(text, err) {632 if (err) {633 // TODO(longsleep): Pure man error conversion follows. This needs real634 // messages for the known errors and translation.635 if (err.msg) {636 err = err.msg;637 } else if (err.code) {638 err = (''+err.code).replace('_', ' ');639 }640 text += ' - ' + err;641 }642 return async dispatch => {643 await dispatch(setError({644 message: text,645 fatal: false,646 }));647 };648}649export function doCall(id, errorCallback) {650 return async dispatch => {651 if (!kwm || !kwm.webrtc) {652 throw new Error('no kwm');653 }654 await dispatch({655 type: types.KWM_DO_CALL,656 id,657 });658 return kwm.webrtc.doCall(id).then(channel => {659 console.info('KWM channel create', channel); // eslint-disable-line no-console660 dispatch(channelChanged(channel));661 return channel;662 }).catch(err => {663 dispatch({664 type: types.KWM_CLEAR_CALLING,665 id,666 });667 dispatch(doHangup(id, '')); // Hangup without reason is a local hangup.668 err = errorCallback ? errorCallback(err) : err;669 if (err) {670 console.error('KWM doCall failed', err); // eslint-disable-line no-console671 dispatch(setNonFatalError(errors.ERROR_KWM_UNABLE_TO_CALL, err));672 }673 });674 };675}676export function doHangup(id='', reason) {677 return async dispatch => {678 // Hangs up all and everyone679 await dispatch({680 type: types.KWM_DO_HANGUP,681 id,682 reason,683 });684 if (!kwm || !kwm.webrtc) {685 return;686 }687 return kwm.webrtc.doHangup(id, reason).then(channel => {688 console.info('KWM channel release', channel); // eslint-disable-line no-console689 dispatch(resetChannel());690 }).catch(err => {691 dispatch(doHangup(id, '')); // Hangup without reason is a local hangup.692 console.error('KWM doHangup failed', err); // eslint-disable-line no-console693 // FIXME(longsleep): Only hang up locally is probably not ideal - maybe694 // an error message should be shown?695 });696 };697}698export function doGroup(id, errorCallback) {699 return async dispatch => {700 if (!kwm || !kwm.webrtc) {701 throw new Error('no kwm');702 }703 await dispatch({704 type: types.KWM_DO_GROUP,705 id,706 });707 return kwm.webrtc.doGroup(id).then(channel => {708 console.info('KWM group channel create', channel); // eslint-disable-line no-console709 dispatch(channelChanged(channel));710 return channel;711 }).catch(err => {712 err = errorCallback ? errorCallback(err) : err;713 if (err) {714 console.error('KWM doGroup failed', err); // eslint-disable-line no-console715 dispatch(setNonFatalError(error.ERROR_KWM_UNABLE_TO_JOIN, err));716 }717 });718 };719}720export function doSendChatMessage(channel, message, errorCallback) {721 return async dispatch => {722 if (!kwm || !kwm.chats) {723 throw new Error('no kwm');724 }725 return kwm.chats.doSendChatMessage(channel, message).then(replyMessage => {726 if (replyMessage === undefined) {727 // NOTE(longsleep): undefined happens when kwmserver rejects the message728 // as this case is currently not handled in kwmjs at the moment.729 throw new Error('no reply data');730 }731 return replyMessage;732 }).catch(err => {733 err = errorCallback ? errorCallback(err) : err;734 if (err) {735 console.error('KWM doSendChatMessage failed', err); // eslint-disable-line no-console736 // TODO(longsleep): Dispatch proper error.737 }738 return null;739 });740 };741}742export function doAccept(id) {743 return async dispatch => {744 if (!kwm || !kwm.webrtc) {745 throw new Error('no kwm');746 }747 await dispatch({748 type: types.KWM_DO_ACCEPT,749 id,750 });751 return kwm.webrtc.doAnswer(id).then(channel => {752 console.info('KWM channel create', channel); // eslint-disable-line no-console753 dispatch(channelChanged(channel));754 return channel;755 }).catch(err => {756 console.error('KWM doAccept failed', err); // eslint-disable-line no-console757 dispatch(setNonFatalError(error.ERROR_KWM_UNABLE_TO_ACCEPT, err));758 });759 };760}761export function doReject(id, reason='reject') {762 return async dispatch => {763 if (!kwm || !kwm.webrtc) {764 throw new Error('no kwm');765 }766 await dispatch({767 type: types.KWM_DO_REJECT,768 id,769 reason,770 });771 return kwm.webrtc.doReject(id, reason).catch(err => {772 console.error('KWM doReject failed', err); // eslint-disable-line no-console773 dispatch(doHangup(id, '')); // Hangup without reason is a local hangup.774 // FIXME(longsleep): Only hang up locally is probably not ideal - maybe775 // an error message should be shown?776 });777 };778}779export function doIgnore(id) {780 return {781 type: types.KWM_DO_IGNORE,782 id,783 };784}785export function setLocalStream(stream) {786 return async () => {787 console.info('KWM setting local stream', stream); // eslint-disable-line no-console788 if (kwm && kwm.webrtc) {789 kwm.webrtc.setLocalStream(stream);790 }791 return stream;792 };793}794export function unsetLocalStream() {795 return async () => {796 console.info('KWM unsetting local stream'); // eslint-disable-line no-console797 if (kwm && kwm.webrtc) {798 kwm.webrtc.setLocalStream(); // clears.799 }800 };801}802export function setScreenshareStream(id, stream) {803 return async () => {804 console.info('KWM setting screen share stream', id, stream); // eslint-disable-line no-console805 if (kwm && kwm.webrtc) {806 kwm.webrtc.setScreenshareStream(id, stream);807 }808 return stream;809 };810}811export function setMode(mode) {812 return async () => {813 if (kwm && kwm.webrtc) {814 kwm.webrtc.setMode(mode);815 }816 };817}818export function updateOfferAnswerConstraints(options) {819 return async () => {820 console.info('KWM update offer/answer constaints', options); // eslint-disable-line no-console821 Object.assign(webrtcOptions.answerConstraints, options);822 Object.assign(webrtcOptions.offerConstraints, options);823 if (kwm && kwm.webrtc) {824 Object.assign(kwm.webrtc.options, webrtcOptions);825 }826 };827}828export function applyLocalStreamTracks(info) {829 return async dispatch => {830 if (!info || !info.stream) {831 return info;832 }833 console.info('KWM updating local stream tracks', info); // eslint-disable-line no-console834 if (kwm && kwm.webrtc) {835 if (info.newStream) {836 return dispatch(setLocalStream(info.newStream));837 }838 for (const track of info.removedTracks) {839 kwm.webrtc.removeLocalStreamTrack(track, info.stream);840 }841 for (const track of info.newTracks) {842 kwm.webrtc.addLocalStreamTrack(track, info.stream);843 }844 }845 return info;846 };847}848export function getStatsForAllConnections() {849 return async (dispatch, getState) => {850 const { connections } = getState().kwm;851 // Implement getStats according to https://www.w3.org/TR/webrtc-stats/#example-of-a-stats-application852 const promises = [];853 for (const id in connections) {854 const c = connections[id];855 if (c._pc) {856 try {857 const senders = c._pc.getSenders();858 const receivers = c._pc.getReceivers();859 senders.forEach(sender => {860 promises.push(sender.getStats());861 });862 receivers.forEach(receiver => {863 promises.push(receiver.getStats());864 });865 } catch (err) {866 console.warn('getStats failed', err); // eslint-disable-line no-console867 }868 }869 }870 if (promises.length === 0) {871 return null;872 }873 const result = {874 transportsBytesSend: 0,875 transportsBytesReceived: 0,876 };877 const reports = await Promise.all(promises);878 reports.forEach(report => {879 for (let record of report.values()) {880 //console.debug('getStats record', record.type, record.bytesSent, record.bytesReceived, record);881 switch (record.type) {882 case 'outbound-rtp':883 result.transportsBytesSend += record.bytesSent;884 break;885 case 'inbound-rtp':886 result.transportsBytesReceived += record.bytesReceived;887 break;888 case 'candidate-pair':889 break;890 default:891 continue;892 }893 if (!result.timestamp && record.timestamp) {894 // NOTE(longsleep): We use only a single timestamp, probably a little off ..895 result.timestamp = record.timestamp;896 }897 }898 });899 return result;900 };901}902export function tryGuestLogon(settings) {903 return dispatch => {904 return dispatch(guestLogon(settings)).catch(err => {905 console.debug('try guest logon failed', err); // eslint-disable-line no-console906 return {907 ok: false,908 };909 });910 };911}912function chatsMessageReceived(event, options={}) {913 const { channel, message, profile } = event;914 return {915 type: types.CHATS_MESSAGES_RECEIVED,916 channel,917 session: 'current',918 messages: [{919 ...message,920 ts: new Date(message.ts * 1000),921 profile,922 }],923 ...options,924 };925}926function chatsSystemReceived(event) {927 return async dispatch => {928 const { channel, message } = event;929 // Filter incoming messages to let only the ones through we know about.930 switch (message.kind) {931 case 'delivery_queued':932 return dispatch({933 type: types.CHATS_MESSAGES_DELIVERY_QUEUED,934 channel,935 session: 'current',936 ids: [message.id],937 });938 case 'system':939 // System message.940 return dispatch(chatsMessageReceived(event, { skipUnreadCounting: true }));941 default:942 console.warn('unknown chats system message kind received', message.kind); // eslint-disable-line no-console943 }944 };...

Full Screen

Full Screen

peercall.js

Source:peercall.js Github

copy

Full Screen

1/*2 * Spreed WebRTC.3 * Copyright (C) 2013-2014 struktur AG4 *5 * This file is part of Spreed WebRTC.6 *7 * This program is free software: you can redistribute it and/or modify8 * it under the terms of the GNU Affero General Public License as published by9 * the Free Software Foundation, either version 3 of the License, or10 * (at your option) any later version.11 *12 * This program is distributed in the hope that it will be useful,13 * but WITHOUT ANY WARRANTY; without even the implied warranty of14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 * GNU Affero General Public License for more details.16 *17 * You should have received a copy of the GNU Affero General Public License18 * along with this program. If not, see <http://www.gnu.org/licenses/>.19 *20 */21"use strict";22define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection'], function($, _, utils, PeerConnection) {23 var PeerCall = function(webrtc, id, from, to) {24 this.webrtc = webrtc;25 this.id = id;26 this.from = from;27 this.to = to;28 this.e = $({}) // events29 this.mediaConstraints = $.extend(true, {}, this.webrtc.settings.mediaConstraints);30 this.pcConfig = $.extend(true, {}, this.webrtc.settings.pcConfig);31 this.pcConstraints = $.extend(true, {}, this.webrtc.settings.pcConstraints);32 this.sdpConstraints = $.extend(true, {}, this.webrtc.settings.sdpConstraints);33 this.offerConstraints = $.extend(true, {}, this.webrtc.settings.offerConstraints);34 this.sdpParams = $.extend(true, {}, this.webrtc.settings.sdpParams);35 this.peerconnection = null;36 this.datachannels = {};37 this.streams = {};38 this.negotiationNeeded = false;39 this.initiate = false;40 this.closed = false;41 };42 PeerCall.prototype.setInitiate = function(initiate) {43 this.initiate = !! initiate;44 //console.log("Set initiate", this.initiate, this);45 };46 PeerCall.prototype.createPeerConnection = function(success_cb, error_cb) {47 var peerconnection = this.peerconnection = new PeerConnection(this.webrtc, this);48 if (success_cb && peerconnection.pc) {49 success_cb(peerconnection);50 }51 if (error_cb && !peerconnection.pc) {52 // TODO(longsleep): Check if this can happen?53 error_cb(peerconnection);54 }55 return peerconnection;56 };57 PeerCall.prototype.createOffer = function(cb) {58 var constraints = utils.mergeConstraints(this.offerConstraints, this.sdpConstraints);59 console.log('Creating offer with constraints: \n' +60 ' \'' + JSON.stringify(constraints, null, '\t') + '\'.', this.negotiationNeeded);61 this.peerconnection.createOffer(_.bind(this.onCreateAnswerOffer, this, cb), _.bind(this.onErrorAnswerOffer, this), constraints);62 };63 PeerCall.prototype.createAnswer = function(cb) {64 console.log("Creating answer.", this.negotiationNeeded);65 this.peerconnection.createAnswer(_.bind(this.onCreateAnswerOffer, this, cb), _.bind(this.onErrorAnswerOffer, this), this.peerconnection.sdpConstraints);66 };67 PeerCall.prototype.onCreateAnswerOffer = function(cb, sessionDescription) {68 this.setLocalSdp(sessionDescription);69 // Convert to object to allow custom property injection.70 var sessionDescriptionObj = sessionDescription;71 if (sessionDescriptionObj.toJSON) {72 sessionDescriptionObj = JSON.parse(JSON.stringify(sessionDescriptionObj));73 }74 console.log("Created offer/answer", JSON.stringify(sessionDescriptionObj, null, "\t"));75 // Allow external session description modifications.76 this.e.triggerHandler("sessiondescription", [sessionDescriptionObj, this]);77 // Always set local description.78 this.peerconnection.setLocalDescription(sessionDescription, _.bind(function() {79 console.log("Set local session description.", sessionDescription, this);80 if (cb) {81 cb(sessionDescriptionObj, this);82 }83 }, this), _.bind(function(err) {84 console.error("Set local session description failed", err);85 this.close();86 this.e.triggerHandler("error", "failed_peerconnection_setup");87 }, this));88 if (this.negotiationNeeded) {89 this.negotiationNeeded = false;90 console.log("Negotiation complete.", this);91 }92 };93 PeerCall.prototype.onErrorAnswerOffer = function(event) {94 console.error("Failed to create answer/offer", event);95 };96 PeerCall.prototype.setRemoteDescription = function(sessionDescription, cb) {97 var peerconnection = this.peerconnection;98 if (!peerconnection) {99 console.log("Got a remote description but not connected -> ignored.");100 return;101 }102 this.setRemoteSdp(sessionDescription);103 peerconnection.setRemoteDescription(sessionDescription, _.bind(function() {104 console.log("Set remote session description.", sessionDescription, this);105 if (cb) {106 cb(sessionDescription, this);107 }108 // NOTE(longsleep): There are several szenarios where onaddstream is never fired, when109 // the peer does not provide a certain stream type (eg. has no camera). See110 // for example https://bugzilla.mozilla.org/show_bug.cgi?id=998546. For this111 // reason we always trigger onRemoteStream added for all streams which are available112 // after the remote SDP was set successfully.113 _.defer(_.bind(function() {114 _.each(peerconnection.getRemoteStreams(), _.bind(function(stream) {115 if (!this.streams.hasOwnProperty(stream.id) && (stream.getAudioTracks().length > 0 || stream.getVideoTracks().length > 0)) {116 // NOTE(longsleep): Add stream here when it has at least one audio or video track, to avoid FF >= 33 to add it multiple times.117 console.log("Adding stream after remote SDP success.", stream);118 this.onRemoteStreamAdded(stream);119 }120 }, this));121 }, this));122 }, this), _.bind(function(err) {123 console.error("Set remote session description failed", err);124 this.close();125 this.e.triggerHandler("error", "failed_peerconnection_setup");126 }, this));127 };128 PeerCall.prototype.setLocalSdp = function(sessionDescription) {129 var params = this.sdpParams;130 sessionDescription.sdp = utils.maybePreferAudioReceiveCodec(sessionDescription.sdp, params);131 sessionDescription.sdp = utils.maybePreferVideoReceiveCodec(sessionDescription.sdp, params);132 sessionDescription.sdp = utils.maybeSetAudioReceiveBitRate(sessionDescription.sdp, params);133 sessionDescription.sdp = utils.maybeSetVideoReceiveBitRate(sessionDescription.sdp, params);134 };135 PeerCall.prototype.setRemoteSdp = function(sessionDescription) {136 var params = this.sdpParams;137 sessionDescription.sdp = utils.maybeSetOpusOptions(sessionDescription.sdp, params);138 sessionDescription.sdp = utils.maybePreferAudioSendCodec(sessionDescription.sdp, params);139 sessionDescription.sdp = utils.maybePreferVideoSendCodec(sessionDescription.sdp, params);140 sessionDescription.sdp = utils.maybeSetAudioSendBitRate(sessionDescription.sdp, params);141 sessionDescription.sdp = utils.maybeSetVideoSendBitRate(sessionDescription.sdp, params);142 sessionDescription.sdp = utils.maybeSetVideoSendInitialBitRate(sessionDescription.sdp, params);143 };144 PeerCall.prototype.onIceCandidate = function(event) {145 if (event.candidate) {146 //console.log("ice candidate", event.candidate);147 var payload = {148 type: 'candidate',149 sdpMLineIndex: event.candidate.sdpMLineIndex,150 sdpMid: event.candidate.sdpMid,151 candidate: event.candidate.candidate152 };153 // Allow external payload modifications.154 this.e.triggerHandler("icecandidate", [payload, this]);155 // Send it.156 // TODO(longsleep): This id needs to be different for PeerXfers.157 // XXX(longsleep): This seems to be breaking conferences when this.to and not this.id.158 this.webrtc.api.sendCandidate(this.to, payload);159 //console.log("Sent candidate", event.candidate.sdpMid, event.candidate.sdpMLineIndex, event.candidate.candidate);160 } else {161 console.log('End of candidates.');162 }163 };164 PeerCall.prototype.onIceConnectionStateChange = function(iceConnectionState) {165 this.e.triggerHandler("connectionStateChange", [iceConnectionState, this]);166 };167 PeerCall.prototype.onRemoteStreamAdded = function(stream) {168 var id = stream.id;169 if (this.streams.hasOwnProperty(id)) {170 return;171 }172 this.streams[id] = stream;173 this.e.triggerHandler("remoteStreamAdded", [stream, this]);174 };175 PeerCall.prototype.onRemoteStreamRemoved = function(stream) {176 this.e.triggerHandler("remoteStreamRemoved", [stream, this]);177 if (stream) {178 delete this.streams[stream.id];179 }180 };181 PeerCall.prototype.onNegotiationNeeded = function() {182 if (!this.negotiationNeeded) {183 this.negotiationNeeded = true;184 console.log("Negotiation needed.", this);185 this.e.triggerHandler("negotiationNeeded", [this]);186 }187 };188 PeerCall.prototype.addIceCandidate = function(candidate) {189 if (this.closed) {190 // Avoid errors when still receiving candidates but closed.191 return;192 }193 this.peerconnection.addIceCandidate(candidate, function() {194 //console.log("Remote candidate added successfully.", candidate);195 }, function(error) {196 console.warn("Failed to add remote candidate:", error, candidate);197 });198 };199 PeerCall.prototype.onDatachannel = function(datachannel) {200 //console.log("onDatachannel", datachannel);201 var label = datachannel.label;202 if (this.datachannels.hasOwnProperty(label)) {203 console.warn("Received duplicated datachannel label", label, datachannel, this.datachannels);204 return;205 }206 // Remember it for correct cleanups.207 this.datachannels[label] = datachannel;208 this.e.triggerHandler("datachannel", ["new", datachannel, this]);209 };210 PeerCall.prototype.onDatachannelDefault = function(state, datachannel) {211 if (state === "open") {212 //console.log("Data ready", this);213 _.defer(_.bind(function() {214 this.e.triggerHandler("dataReady", [this]);215 }, this));216 }217 this.e.triggerHandler("datachannel.default", [state, datachannel, this]);218 };219 PeerCall.prototype.onMessage = function(event) {220 //console.log("Peer to peer channel message", event);221 var data = event.data;222 if (data instanceof Blob) {223 console.warn("Blob data received - not implemented.", data);224 } else if (data instanceof ArrayBuffer) {225 console.warn("ArrayBuffer data received - not implemented.", data);226 } else if (typeof data === "string") {227 if (data.charCodeAt(0) === 2) {228 // Ignore whatever shit is this (sent by Chrome 34 and FireFox). Feel free to229 // change the comment it you know what this is.230 return;231 }232 //console.log("Datachannel message", [event.data, event.data.length, event.data.charCodeAt(0)]);233 var msg = JSON.parse(event.data);234 this.webrtc.api.received({235 Type: msg.Type,236 Data: msg,237 To: this.webrtc.api.id,238 From: this.id,239 p2p: true240 }); //XXX(longsleep): use event for this?241 } else {242 console.warn("Unknow data type received -> igored", typeof data, [data]);243 }244 };245 PeerCall.prototype.getDatachannel = function(label, init, create_cb) {246 //console.log("getDatachannel", label);247 var datachannel = this.datachannels[label];248 if (!datachannel) {249 console.log("Creating new datachannel", label, init);250 datachannel = this.peerconnection.createDatachannel(label, init);251 if (create_cb) {252 create_cb(datachannel);253 }254 }255 return datachannel;256 };257 PeerCall.prototype.close = function() {258 if (this.closed) {259 return;260 }261 this.closed = true;262 _.each(this.datachannels, function(datachannel) {263 datachannel.close();264 });265 this.datachannels = {};266 if (this.peerconnection) {267 this.peerconnection.close();268 this.peerconnection = null;269 }270 // Trigger event for all previously added streams.271 _.each(this.streams, _.bind(function(stream, id) {272 this.e.triggerHandler("remoteStreamRemoved", [stream, this]);273 }, this));274 this.streams = {};275 console.log("Peercall close", this);276 this.e.triggerHandler("closed", [this]);277 };278 return PeerCall;...

Full Screen

Full Screen

asyncbox-specs.js

Source:asyncbox-specs.js Github

copy

Full Screen

...15});16describe('longSleep', function () {17 it('should work like sleep in general', async function () {18 let now = Date.now();19 await longSleep(20);20 (Date.now() - now).should.be.above(19);21 });22 it('should work like sleep with values less than threshold', async function () {23 const now = Date.now();24 await longSleep(20, {thresholdMs: 100});25 (Date.now() - now).should.be.above(19);26 });27 it('should work like sleep with values above threshold, but quantized', async function () {28 const now = Date.now();29 await longSleep(50, {thresholdMs: 20, intervalMs: 40});30 (Date.now() - now).should.be.above(79);31 });32 it('should trigger a progress callback if specified', async function () {33 let callCount = 0;34 let curElapsed = 0;35 let curTimeLeft = 10000;36 let curProgress = 0;37 const progressCb = function ({elapsedMs, timeLeft, progress}) {38 elapsedMs.should.be.above(curElapsed);39 timeLeft.should.be.below(curTimeLeft);40 progress.should.be.above(curProgress);41 curElapsed = elapsedMs;42 curTimeLeft = timeLeft;43 curProgress = progress;44 callCount += 1;45 };46 const now = Date.now();47 await longSleep(500, {thresholdMs: 1, intervalMs: 100, progressCb});48 (Date.now() - now).should.be.above(49);49 callCount.should.be.above(3);50 (curProgress >= 1).should.be.true;51 (curTimeLeft <= 0).should.be.true;52 (curElapsed >= 50).should.be.true;53 });54});55describe('retry', function () {56 let okFnCalls = 0;57 let okFn = async function (val1, val2) {58 await sleep(15);59 okFnCalls++;60 return val1 * val2;61 };...

Full Screen

Full Screen

peerconnection.js

Source:peerconnection.js Github

copy

Full Screen

1"use strict";2define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {3 var count = 0;4 var dataChannelDefaultLabel = "default";5 var PeerConnection = function(webrtc, currentcall) {6 this.webrtc = webrtc;7 this.id = count++;8 this.currentcall = null;9 this.pc = null;10 this.datachannel = null;11 this.datachannelReady = false;12 this.readyForRenegotiation = true;13 if (currentcall) {14 this.createPeerConnection(currentcall);15 }16 };17 PeerConnection.prototype.setReadyForRenegotiation = function(ready) {18 this.readyForRenegotiation = !!ready;19 };20 PeerConnection.prototype.createPeerConnection = function(currentcall) {21 // XXX(longsleep): This function is a mess.22 var pc;23 if (currentcall) {24 this.currentcall = currentcall;25 } else {26 currentcall = this.currentcall;27 }28 try {29 // Create an RTCPeerConnection via the polyfill (adapter.js)30 console.log('Creating RTCPeerConnnection with:\n' +31 ' config: \'' + JSON.stringify(currentcall.pcConfig) + '\';\n' +32 ' constraints: \'' + JSON.stringify(currentcall.pcConstraints) + '\'.');33 pc = this.pc = new window.RTCPeerConnection(currentcall.pcConfig, currentcall.pcConstraints);34 } catch (e) {35 console.error('Failed to create PeerConnection, exception: ' + e.message);36 pc = this.pc = null;37 }38 if (pc) {39 // Bind peer connection events.40 pc.onicecandidate = _.bind(currentcall.onIceCandidate, currentcall);41 pc.oniceconnectionstatechange = _.bind(this.onIceConnectionStateChange, this)42 // NOTE(longsleep): There are several szenarios where onaddstream is never fired, when43 // the peer does not provide a certain stream type (eg. has no camera). See44 // for example https://bugzilla.mozilla.org/show_bug.cgi?id=998546.45 pc.onaddstream = _.bind(this.onRemoteStreamAdded, this);46 pc.onremovestream = _.bind(this.onRemoteStreamRemoved, this);47 // NOTE(longsleep): Firefox 38 has support for onaddtrack. Unfortunately Chrome does48 // not support this and thus both are not compatible. For the time being this means49 // that renegotiation does not work between Firefox and Chrome. Even worse, current50 // spec says that the event should really be named ontrack.51 if (window.webrtcDetectedBrowser === "firefox") {52 // NOTE(longsleep): onnegotiationneeded is not supported by Firefox < 38.53 // Also firefox does not care about streams, but has the newer API for tracks54 // implemented. This does not work together with Chrome, so we trigger negotiation55 // manually when a stream is added or removed.56 // https://bugzilla.mozilla.org/show_bug.cgi?id=101788857 // https://bugzilla.mozilla.org/show_bug.cgi?id=114983858 this.negotiationNeeded = _.bind(function() {59 if (this.currentcall.initiate) {60 // Trigger onNegotiationNeeded once for Firefox.61 console.log("Negotiation needed.");62 this.onNegotiationNeeded({target: this.pc});63 }64 }, this);65 } else {66 pc.onnegotiationneeded = _.bind(this.onNegotiationNeeded, this);67 }68 pc.ondatachannel = _.bind(this.onDatachannel, this);69 pc.onsignalingstatechange = _.bind(this.onSignalingStateChange, this);70 // NOTE(longsleep):71 // Support old callback too (https://groups.google.com/forum/?fromgroups=#!topic/discuss-webrtc/glukq0OWwVM)72 // Chrome < 27 and Firefox < 24 need this.73 pc.onicechange = _.bind(function(iceConnectionState) {74 //XXX(longsleep): Hack the compatibility to new style event.75 console.warn("Old style onicechange event", arguments);76 this.onIceConnectionStateChange({77 target: {78 iceConnectionState: iceConnectionState79 }80 });81 }, this);82 // Create default data channel when we are in initiate mode.83 if (currentcall.initiate) {84 if (window.webrtcDetectedBrowser !== "chrome" || !window.webrtcDetectedAndroid || (window.webrtcDetectedBrowser === "chrome" && window.webrtcDetectedVersion >= 33)) {85 // NOTE(longsleep): Android (Chrome 32) does have broken SCTP data channels86 // which makes connection fail because of sdp set error for answer/offer.87 // See https://code.google.com/p/webrtc/issues/detail?id=2253 Lets hope the88 // crap gets fixed with Chrome on Android 33. For now disable SCTP in flags89 // on Adroid to be able to accept offers with SCTP in it.90 // chrome://flags/#disable-sctp-data-channels91 this.createDatachannel(dataChannelDefaultLabel, {92 ordered: true93 });94 }95 }96 }97 return pc;98 };99 PeerConnection.prototype.negotiationNeeded = function() {100 // Per default this does nothing as the browser is expected to handle this.101 };102 PeerConnection.prototype.createDatachannel = function(label, init) {103 if (!label) {104 console.error("Refusing to create a datachannel without a label.", label, init);105 return;106 }107 var rtcinit = $.extend({}, init);108 console.debug("Creating datachannel:", label, rtcinit, this);109 // Create datachannel.110 var datachannel;111 try {112 datachannel = this.pc.createDataChannel(label, rtcinit);113 // Fake onDatachannel event.114 this.onDatachannel({115 channel: datachannel116 });117 } catch (e) {118 console.error('Failed to create DataChannel, exception: ' + e.message);119 if (label === dataChannelDefaultLabel) {120 this.datachannel = null;121 this.datachannelReady = false;122 }123 }124 return datachannel;125 };126 PeerConnection.prototype.onDatachannel = function(event) {127 var datachannel = event.channel;128 if (datachannel) {129 if (datachannel.label === dataChannelDefaultLabel) {130 datachannel.binaryType = "arraybuffer";131 // We handle the default data channel ourselves.132 console.debug("Got default datachannel", datachannel.label, this.id, datachannel, this);133 this.datachannel = datachannel;134 var eventHandler = _.bind(this.currentcall.onDatachannelDefault, this.currentcall);135 // Bind datachannel events and settings.136 datachannel.onmessage = _.bind(this.currentcall.onMessage, this.currentcall);137 datachannel.onopen = _.bind(function(event) {138 console.log("Datachannel opened", datachannel.label, this.id, event);139 this.datachannelReady = true;140 eventHandler("open", datachannel);141 }, this);142 datachannel.onclose = _.bind(function(event) {143 console.log("Datachannel closed", datachannel.label, this.id, event);144 this.datachannelReady = false;145 eventHandler("close", datachannel);146 }, this);147 datachannel.onerror = _.bind(function(event) {148 console.warn("Datachannel error", datachannel.label, this.id, event);149 this.datachannelReady = false;150 eventHandler("error", datachannel);151 }, this);152 } else {153 // Delegate.154 console.debug("Got datachannel", datachannel.label, this.id, datachannel);155 _.defer(_.bind(this.currentcall.onDatachannel, this.currentcall), datachannel);156 }157 }158 };159 PeerConnection.prototype.send = function(data) {160 if (!this.datachannelReady) {161 console.error("Unable to send message by datachannel because datachannel is not ready.", data);162 return;163 }164 if (data instanceof Blob) {165 this.datachannel.send(data);166 } else if (data instanceof ArrayBuffer) {167 this.datachannel.send(data);168 } else {169 try {170 this.datachannel.send(JSON.stringify(data));171 } catch (e) {172 console.warn("Data channel failed to send string -> closing.", e);173 this.datachannelReady = false;174 this.datachannel.close();175 }176 }177 };178 PeerConnection.prototype.onSignalingStateChange = function(event) {179 var signalingState = event.target.signalingState;180 console.debug("Connection signaling state change", signalingState, this.currentcall.id);181 this.currentcall.onSignalingStateChange(signalingState);182 };183 PeerConnection.prototype.onIceConnectionStateChange = function(event) {184 var iceConnectionState = event.target.iceConnectionState;185 console.debug("ICE connection state change", iceConnectionState, this.currentcall.id);186 this.currentcall.onIceConnectionStateChange(iceConnectionState);187 };188 PeerConnection.prototype.onRemoteStreamAdded = function(event) {189 var stream = event.stream;190 console.info('Remote stream added.', stream);191 this.currentcall.onRemoteStreamAdded(stream);192 };193 PeerConnection.prototype.onRemoteStreamRemoved = function(event) {194 var stream = event.stream;195 console.info('Remote stream removed.', stream);196 this.currentcall.onRemoteStreamRemoved(stream);197 };198 PeerConnection.prototype.onNegotiationNeeded = function(event) {199 var peerconnection = event.target;200 if (peerconnection === this.pc) {201 this.currentcall.onNegotiationNeeded();202 }203 };204 PeerConnection.prototype.close = function() {205 if (this.datachannel) {206 this.datachannel.close()207 }208 if (this.pc) {209 this.pc.close();210 }211 this.datachannel = null;212 this.pc = null;213 };214 PeerConnection.prototype.hasRemoteDescription = function() {215 // NOTE(longsleep): Chrome seems to return empty sdp even if no remoteDescription was set.216 if (!this.pc || !this.pc.remoteDescription || !this.pc.remoteDescription.sdp) {217 return false218 }219 return true;220 };221 PeerConnection.prototype.setRemoteDescription = function() {222 return this.pc.setRemoteDescription.apply(this.pc, arguments);223 };224 PeerConnection.prototype.setLocalDescription = function() {225 return this.pc.setLocalDescription.apply(this.pc, arguments);226 };227 PeerConnection.prototype.addIceCandidate = function() {228 return this.pc.addIceCandidate.apply(this.pc, arguments);229 };230 PeerConnection.prototype.addStream = function() {231 _.defer(this.negotiationNeeded);232 return this.pc.addStream.apply(this.pc, arguments);233 };234 PeerConnection.prototype.removeStream = function() {235 _.defer(this.negotiationNeeded);236 return this.pc.removeStream.apply(this.pc, arguments);237 };238 PeerConnection.prototype.createAnswer = function() {239 return this.pc.createAnswer.apply(this.pc, arguments);240 };241 PeerConnection.prototype.createOffer = function() {242 return this.pc.createOffer.apply(this.pc, arguments);243 };244 PeerConnection.prototype.getRemoteStreams = function() {245 if (!this.pc) {246 return [];247 }248 return this.pc.getRemoteStreams.apply(this.pc, arguments);249 };250 PeerConnection.prototype.getLocalStreams = function() {251 if (!this.pc) {252 return [];253 }254 return this.pc.getRemoteStreams.apply(this.pc, arguments);255 };256 PeerConnection.prototype.getStreamById = function() {257 return this.pc.getStreamById.apply(this.pc, arguments);258 };259 return PeerConnection;...

Full Screen

Full Screen

CopperMiner.js

Source:CopperMiner.js Github

copy

Full Screen

1var robot = require('robotjs');2var shortsleep = getRandomInt(100, 700);3var mediumSleep = getRandomInt(1200, 2000);4var longSleep = getRandomInt(2100, 5000);5var extraSleep = getRandomInt(5100, 9832);6// console.log(robot.getPixelColor(1164, 521))7// console.log(robot.getPixelColor(1309, 515))8// console.log(robot.getPixelColor(1145, 437))9// console.log(robot.getPixelColor(1216, 385))10// console.log(robot.getPixelColor(1097, 362))11// console.log(robot.getPixelColor(1031, 411))12// console.log(robot.getPixelColor(1154, 504))13var endInventory_x = 1889, endInventory_y = 930, beginningInventory_x = 1743, beginningInventory_y = 715;14var copperOreInventoryColor = "cc6a2a", tinOreInventoryColor = "746b6b";15var endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);16var copperOre_x, copperOre_y, endingTinOre_x, endingTinOre_y;17var caveExit_x = 1122, caveExit_y = 444, compassLocation_x = 1695, compassLocation_y = 78;18var besideBank_x = 1341, besideBank_y = 118, bank_x = 859, bank_y = 302;19var bankOreBox_x = 777, bankOreBox_y = 490, faceSouth_x = compassLocation_x, faceSouth_y = compassLocation_y + 45;20var caveFront_x = 1087, caveFront_y = 110, caveEntrance_x = 1731, caveEntrance_y = 525;21copperOre_x = 958;22copperOre_y = 508;23endingTinOre_x = 917;24endingTinOre_y = 594;25Miner();26function Miner() {27 console.log("Initialzing client...");28 sleep(mediumSleep);29 while (true) {30 var endInventory_x = 1889, endInventory_y = 930;31 var tinOreInventoryColor = "746b6b";32 var endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);33 var startingTinOre_x = 803, startingTinOre_y = 883, startingCopperOre_x = 903, startingCopperOre_y = 474;34 console.log("Beginning to mine copper ore.")35 mineCopper();36 console.log("Filled up on copper ore. Now mining tin ore.")37 robot.moveMouseSmooth(startingTinOre_x, startingTinOre_y);38 sleep(shortsleep);39 robot.mouseClick();40 mineTin();41 console.log("Filling up inventory for the final time.");42 robot.moveMouseSmooth(endingTinOre_x, endingTinOre_y);43 sleep(shortsleep);44 robot.mouseClick();45 while (endInventoryPixelColor != tinOreInventoryColor) {46 sleep(longSleep);47 robot.mouseClick();48 endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);49 }50 goToBank();51 console.log("Going back to the original spot.");52 robot.moveMouseSmooth(startingCopperOre_x, startingCopperOre_y);53 sleep(shortsleep);54 robot.mouseClick();55 56 console.log("Ending loop...");57 }58}59function mineCopper() {60 for (i = 0; i < 4; i++) {61 console.log("Copper ore inventory number: " + i);62 sleep(shortsleep);63 robot.moveMouseSmooth(copperOre_x, copperOre_y);64 sleep(shortsleep);65 robot.mouseClick();66 endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);67 while (endInventoryPixelColor != copperOreInventoryColor) {68 sleep(longSleep);69 robot.mouseClick();70 console.log("Waiting to fill inventory with copper ore...");71 endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);72 }73 console.log("Filling up ore box with copper ore.");74 sleep(shortsleep);75 robot.moveMouseSmooth(beginningInventory_x, beginningInventory_y);76 sleep(shortsleep);77 robot.mouseClick();78 }79}80function mineTin() {81 for (i = 0; i < 4; i++) {82 console.log("Tin ore inventory number: " + i);83 sleep(mediumSleep);84 robot.moveMouseSmooth(endingTinOre_x, endingTinOre_y);85 sleep(shortsleep)86 robot.mouseClick();87 endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);88 while (endInventoryPixelColor != tinOreInventoryColor) {89 sleep(longSleep);90 robot.mouseClick();91 console.log("Waiting to fill inventory up with tin ore...");92 endInventoryPixelColor = robot.getPixelColor(endInventory_x, endInventory_y);93 }94 95 console.log("Filling up ore box with tin ore.");96 sleep(shortsleep);97 robot.moveMouseSmooth(beginningInventory_x, beginningInventory_y);98 sleep(shortsleep);99 robot.mouseClick();100 }101}102function goToBank() {103 console.log("Leaving cave.");104 sleep(shortsleep);105 robot.moveMouseSmooth(caveExit_x, caveExit_y);106 sleep(shortsleep);107 robot.mouseClick();108 sleep(longSleep);109 console.log("Facing north.");110 robot.moveMouseSmooth(compassLocation_x, compassLocation_y);111 sleep(shortsleep);112 robot.mouseClick();113 sleep(shortsleep);114 console.log("Going to bank.");115 robot.moveMouseSmooth(besideBank_x, besideBank_y);116 sleep(shortsleep);117 robot.mouseClick();118 sleep(extraSleep);119 console.log("Banking.");120 robot.moveMouseSmooth(bank_x, bank_y);121 sleep(shortsleep);122 robot.mouseClick();123 sleep(mediumSleep);124 console.log("Depositing inventory.");125 robot.keyTap("3");126 sleep(shortsleep);127 console.log("Getting ore box back.");128 robot.moveMouseSmooth(bankOreBox_x, bankOreBox_y);129 sleep(shortsleep);130 robot.mouseClick();131 sleep(shortsleep);132 console.log("Leaving bank.");133 robot.keyTap("escape");134 sleep(shortsleep);135 console.log("Facing south.");136 robot.moveMouseSmooth(compassLocation_x, compassLocation_y);137 sleep(shortsleep);138 robot.mouseClick("right");139 sleep(shortsleep);140 robot.moveMouseSmooth(faceSouth_x, faceSouth_y);141 sleep(shortsleep);142 robot.mouseClick();143 sleep(shortsleep);144 console.log("Going beside cave.");145 robot.moveMouseSmooth(caveFront_x, caveFront_y);146 sleep(shortsleep);147 robot.mouseClick();148 sleep(extraSleep);149 console.log("Entering cave.");150 robot.moveMouseSmooth(caveEntrance_x, caveEntrance_y);151 sleep(shortsleep);152 robot.mouseClick();153 sleep(mediumSleep);154 console.log("Facing north.");155 robot.moveMouseSmooth(compassLocation_x, compassLocation_y);156 sleep(shortsleep);157 robot.mouseClick()158 sleep(shortsleep);159}160function sleep(ms) {161 Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);162}163function getRandomInt(min, max) {164 min = Math.ceil(min);165 max = Math.floor(max);166 return Math.floor(Math.random() * (max - min + 1)) + min;...

Full Screen

Full Screen

loadPricingContext.js

Source:loadPricingContext.js Github

copy

Full Screen

...51 });52 i += delta;53 helper.shortSleep();54 }55 helper.longSleep();56 helper.writeToTopic(task.workflowInstanceId);57 await koor.postStatus(task, {58 status: "InProgress",59 message: `${global_percentage +60 allocated_percentage}% Load ${what} PTF DONE`61 });62}63koor.pollingLoop(namespace, name, async task => {64 await load(task, "position", 0, 25);65 await load(task, "products", 25, 25);66 await load(task, "static data", 50, 25);67 await load(task, "market data", 75, 25);68 helper.longSleep();69 await koor.postStatus(task, {70 status: "Completed",71 outputValues: {72 id_ref_data: uuid()73 }74 });...

Full Screen

Full Screen

metamask-sign-auto.js

Source:metamask-sign-auto.js Github

copy

Full Screen

1/*2 * @Title: Metamask Sign Auto3 * @Description: Automatically signs trivial metamask signature requests4 */5(function () {6 let clicks = 0;7 const sleep = 150;8 const longSleep = 3000;9 let clickSign = () => {10 let div = document.getElementsByClassName('request-signature__rows')[0];11 if (!div) return;12 if (!div.innerText.includes('I would like to follow user')) return;13 Array.from(document.getElementsByClassName('button')).filter((el) => el.getAttribute('data-testid') && el.getAttribute('data-testid') == 'request-signature__sign').forEach((el) => el.click());14 console.log('clicks:' + (++clicks));15 if (clicks % 50 == 0) {16 console.log('sleeping...');17 setTimeout(clickSign, longSleep);18 } else {19 setTimeout(clickSign, sleep);20 }21 };22 setTimeout(clickSign, 5000);...

Full Screen

Full Screen

helper.js

Source:helper.js Github

copy

Full Screen

...6}7function shortSleep() {8 randomSleep(1);9}10function longSleep() {11 randomSleep(5);12}13function writeToTopic(topic) {14 if (!fs.existsSync(dir)) {15 console.log("topics folder doesn't exist, creating it");16 fs.mkdirSync(dir);17 }18 console.log("writeToTopic", topic);19 fs.closeSync(fs.openSync(dir + topic, "w"));20}21function readFromTopic(topic) {22 while (!fs.existsSync(dir + topic)) {23 console.log("readFromTopic", topic);24 longSleep();25 }26}27module.exports = {28 shortSleep,29 longSleep,30 writeToTopic,31 readFromTopic...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Android Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful