mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1122032 Part 2 - Show the Loop screenshare video in place of the remote video for now. r=mikedeboer
This commit is contained in:
parent
bd23ef68d0
commit
b729195eb0
@ -898,7 +898,7 @@ loop.conversationViews = (function(mozL10n) {
|
|||||||
React.createElement("div", {className: "conversation"},
|
React.createElement("div", {className: "conversation"},
|
||||||
React.createElement("div", {className: "media nested"},
|
React.createElement("div", {className: "media nested"},
|
||||||
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
||||||
React.createElement("div", {className: "video_inner remote"})
|
React.createElement("div", {className: "video_inner remote remote-stream"})
|
||||||
),
|
),
|
||||||
React.createElement("div", {className: localStreamClasses})
|
React.createElement("div", {className: localStreamClasses})
|
||||||
),
|
),
|
||||||
|
@ -898,7 +898,7 @@ loop.conversationViews = (function(mozL10n) {
|
|||||||
<div className="conversation">
|
<div className="conversation">
|
||||||
<div className="media nested">
|
<div className="media nested">
|
||||||
<div className="video_wrapper remote_wrapper">
|
<div className="video_wrapper remote_wrapper">
|
||||||
<div className="video_inner remote"></div>
|
<div className="video_inner remote remote-stream"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className={localStreamClasses}></div>
|
<div className={localStreamClasses}></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -274,7 +274,7 @@ loop.roomViews = (function(mozL10n) {
|
|||||||
React.createElement("div", {className: "conversation room-conversation"},
|
React.createElement("div", {className: "conversation room-conversation"},
|
||||||
React.createElement("div", {className: "media nested"},
|
React.createElement("div", {className: "media nested"},
|
||||||
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
||||||
React.createElement("div", {className: "video_inner remote"})
|
React.createElement("div", {className: "video_inner remote remote-stream"})
|
||||||
),
|
),
|
||||||
React.createElement("div", {className: localStreamClasses}),
|
React.createElement("div", {className: localStreamClasses}),
|
||||||
React.createElement("div", {className: "screen hide"})
|
React.createElement("div", {className: "screen hide"})
|
||||||
|
@ -274,7 +274,7 @@ loop.roomViews = (function(mozL10n) {
|
|||||||
<div className="conversation room-conversation">
|
<div className="conversation room-conversation">
|
||||||
<div className="media nested">
|
<div className="media nested">
|
||||||
<div className="video_wrapper remote_wrapper">
|
<div className="video_wrapper remote_wrapper">
|
||||||
<div className="video_inner remote"></div>
|
<div className="video_inner remote remote-stream"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className={localStreamClasses}></div>
|
<div className={localStreamClasses}></div>
|
||||||
<div className="screen hide"></div>
|
<div className="screen hide"></div>
|
||||||
|
@ -231,7 +231,7 @@
|
|||||||
|
|
||||||
/* Side by side video elements */
|
/* Side by side video elements */
|
||||||
|
|
||||||
.conversation .media.side-by-side .remote {
|
.conversation .media.side-by-side .remote-stream {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
@ -509,7 +509,7 @@
|
|||||||
max-height: none;
|
max-height: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation .media.nested .remote {
|
.conversation .media.nested .remote-stream {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute; /* workaround for lack of object-fit; see bug 1020445 */
|
position: absolute; /* workaround for lack of object-fit; see bug 1020445 */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -218,6 +218,13 @@ loop.shared.actions = (function() {
|
|||||||
state: String
|
state: String
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to notify that a shared screen is being received (or not).
|
||||||
|
*/
|
||||||
|
ReceivingScreenShare: Action.define("receivingScreenShare", {
|
||||||
|
receiving: Boolean
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new room.
|
* Creates a new room.
|
||||||
* XXX: should move to some roomActions module - refs bug 1079284
|
* XXX: should move to some roomActions module - refs bug 1079284
|
||||||
|
@ -73,7 +73,8 @@ loop.store.ActiveRoomStore = (function() {
|
|||||||
used: false,
|
used: false,
|
||||||
localVideoDimensions: {},
|
localVideoDimensions: {},
|
||||||
remoteVideoDimensions: {},
|
remoteVideoDimensions: {},
|
||||||
screenSharingState: SCREEN_SHARE_STATES.INACTIVE
|
screenSharingState: SCREEN_SHARE_STATES.INACTIVE,
|
||||||
|
receivingScreenShare: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -121,6 +122,7 @@ loop.store.ActiveRoomStore = (function() {
|
|||||||
"connectionFailure",
|
"connectionFailure",
|
||||||
"setMute",
|
"setMute",
|
||||||
"screenSharingState",
|
"screenSharingState",
|
||||||
|
"receivingScreenShare",
|
||||||
"remotePeerDisconnected",
|
"remotePeerDisconnected",
|
||||||
"remotePeerConnected",
|
"remotePeerConnected",
|
||||||
"windowUnload",
|
"windowUnload",
|
||||||
@ -380,6 +382,13 @@ loop.store.ActiveRoomStore = (function() {
|
|||||||
this.setStoreState({screenSharingState: actionData.state});
|
this.setStoreState({screenSharingState: actionData.state});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to note the current state of receiving screenshare data.
|
||||||
|
*/
|
||||||
|
receivingScreenShare: function(actionData) {
|
||||||
|
this.setStoreState({receivingScreenShare: actionData.receiving});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles recording when a remote peer has connected to the servers.
|
* Handles recording when a remote peer has connected to the servers.
|
||||||
*/
|
*/
|
||||||
|
@ -259,7 +259,8 @@ loop.shared.mixins = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the dimensions of the remote video stream.
|
* Retrieve the dimensions of the active remote video stream. This assumes
|
||||||
|
* that if screens are being shared, the remote camera stream is hidden.
|
||||||
* Example output:
|
* Example output:
|
||||||
* {
|
* {
|
||||||
* width: 680,
|
* width: 680,
|
||||||
@ -270,6 +271,8 @@ loop.shared.mixins = (function() {
|
|||||||
* offsetY: 0
|
* offsetY: 0
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
* Note: This expects a class on the element that has the name "remote" or the
|
||||||
|
* same name as the possible video types (currently only "screen").
|
||||||
* Note: Once we support multiple remote video streams, this function will
|
* Note: Once we support multiple remote video streams, this function will
|
||||||
* need to be updated.
|
* need to be updated.
|
||||||
* @return {Object} contains the remote stream dimension properties of its
|
* @return {Object} contains the remote stream dimension properties of its
|
||||||
@ -320,7 +323,7 @@ loop.shared.mixins = (function() {
|
|||||||
|
|
||||||
// Calculate the size of each individual letter- or pillarbox for convenience.
|
// Calculate the size of each individual letter- or pillarbox for convenience.
|
||||||
remoteVideoDimensions.offsetX = remoteVideoDimensions.width -
|
remoteVideoDimensions.offsetX = remoteVideoDimensions.width -
|
||||||
remoteVideoDimensions.streamWidth
|
remoteVideoDimensions.streamWidth;
|
||||||
if (remoteVideoDimensions.offsetX > 0) {
|
if (remoteVideoDimensions.offsetX > 0) {
|
||||||
remoteVideoDimensions.offsetX /= 2;
|
remoteVideoDimensions.offsetX /= 2;
|
||||||
}
|
}
|
||||||
@ -351,18 +354,22 @@ loop.shared.mixins = (function() {
|
|||||||
this._bufferedUpdateVideo = null;
|
this._bufferedUpdateVideo = null;
|
||||||
var localStreamParent = this._getElement(".local .OT_publisher");
|
var localStreamParent = this._getElement(".local .OT_publisher");
|
||||||
var remoteStreamParent = this._getElement(".remote .OT_subscriber");
|
var remoteStreamParent = this._getElement(".remote .OT_subscriber");
|
||||||
|
var screenShareStreamParent = this._getElement('.screen .OT_subscriber');
|
||||||
if (localStreamParent) {
|
if (localStreamParent) {
|
||||||
localStreamParent.style.width = "100%";
|
localStreamParent.style.width = "100%";
|
||||||
}
|
}
|
||||||
if (remoteStreamParent) {
|
if (remoteStreamParent) {
|
||||||
remoteStreamParent.style.height = "100%";
|
remoteStreamParent.style.height = "100%";
|
||||||
}
|
}
|
||||||
|
if (screenShareStreamParent) {
|
||||||
|
screenShareStreamParent.style.height = "100%";
|
||||||
|
}
|
||||||
|
|
||||||
// Update the position and dimensions of the containers of local video
|
// Update the position and dimensions of the containers of local video
|
||||||
// streams, if necessary. The consumer of this mixin should implement the
|
// streams, if necessary. The consumer of this mixin should implement the
|
||||||
// actual updating mechanism.
|
// actual updating mechanism.
|
||||||
Object.keys(this._videoDimensionsCache.local).forEach(function(videoType) {
|
Object.keys(this._videoDimensionsCache.local).forEach(function(videoType) {
|
||||||
var ratio = this._videoDimensionsCache.local[videoType].aspectRatio
|
var ratio = this._videoDimensionsCache.local[videoType].aspectRatio;
|
||||||
if (videoType == "camera" && this.updateLocalCameraPosition) {
|
if (videoType == "camera" && this.updateLocalCameraPosition) {
|
||||||
this.updateLocalCameraPosition(ratio);
|
this.updateLocalCameraPosition(ratio);
|
||||||
}
|
}
|
||||||
|
@ -136,6 +136,7 @@ loop.OTSdkDriver = (function() {
|
|||||||
|
|
||||||
this.session.on("connectionCreated", this._onConnectionCreated.bind(this));
|
this.session.on("connectionCreated", this._onConnectionCreated.bind(this));
|
||||||
this.session.on("streamCreated", this._onRemoteStreamCreated.bind(this));
|
this.session.on("streamCreated", this._onRemoteStreamCreated.bind(this));
|
||||||
|
this.session.on("streamDestroyed", this._onRemoteStreamDestroyed.bind(this));
|
||||||
this.session.on("connectionDestroyed",
|
this.session.on("connectionDestroyed",
|
||||||
this._onConnectionDestroyed.bind(this));
|
this._onConnectionDestroyed.bind(this));
|
||||||
this.session.on("sessionDisconnected",
|
this.session.on("sessionDisconnected",
|
||||||
@ -280,6 +281,30 @@ loop.OTSdkDriver = (function() {
|
|||||||
this.dispatcher.dispatch(new sharedActions.RemotePeerConnected());
|
this.dispatcher.dispatch(new sharedActions.RemotePeerConnected());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles when a remote screen share is created, subscribing to
|
||||||
|
* the stream, and notifying the stores that a share is being
|
||||||
|
* received.
|
||||||
|
*
|
||||||
|
* @param {Stream} stream The SDK Stream:
|
||||||
|
* https://tokbox.com/opentok/libraries/client/js/reference/Stream.html
|
||||||
|
*/
|
||||||
|
_handleRemoteScreenShareCreated: function(stream) {
|
||||||
|
if (!this.getScreenShareElementFunc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let the stores know first so they can update the display.
|
||||||
|
this.dispatcher.dispatch(new sharedActions.ReceivingScreenShare({
|
||||||
|
receiving: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
var remoteElement = this.getScreenShareElementFunc();
|
||||||
|
|
||||||
|
this.session.subscribe(stream,
|
||||||
|
remoteElement, this._getCopyPublisherConfig());
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the event when the remote stream is created.
|
* Handles the event when the remote stream is created.
|
||||||
*
|
*
|
||||||
@ -295,14 +320,13 @@ loop.OTSdkDriver = (function() {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteElement;
|
|
||||||
if (event.stream.videoType === "screen") {
|
if (event.stream.videoType === "screen") {
|
||||||
// XXX Implement in part 2.
|
this._handleRemoteScreenShareCreated(event.stream);
|
||||||
remoteElement = "null";
|
return;
|
||||||
} else {
|
|
||||||
remoteElement = this.getRemoteElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var remoteElement = this.getRemoteElement();
|
||||||
|
|
||||||
this.session.subscribe(event.stream,
|
this.session.subscribe(event.stream,
|
||||||
remoteElement, this._getCopyPublisherConfig());
|
remoteElement, this._getCopyPublisherConfig());
|
||||||
|
|
||||||
@ -328,6 +352,25 @@ loop.OTSdkDriver = (function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the event when the remote stream is destroyed.
|
||||||
|
*
|
||||||
|
* @param {StreamEvent} event The event details:
|
||||||
|
* https://tokbox.com/opentok/libraries/client/js/reference/StreamEvent.html
|
||||||
|
*/
|
||||||
|
_onRemoteStreamDestroyed: function(event) {
|
||||||
|
if (event.stream.videoType !== "screen") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All we need to do is notify the store we're no longer receiving,
|
||||||
|
// the sdk should do the rest.
|
||||||
|
this.dispatcher.dispatch(new sharedActions.ReceivingScreenShare({
|
||||||
|
receiving: false
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the sdk when the media access dialog is opened.
|
* Called from the sdk when the media access dialog is opened.
|
||||||
* Prevents the default action, to prevent the SDK's "allow access"
|
* Prevents the default action, to prevent the SDK's "allow access"
|
||||||
|
@ -358,7 +358,7 @@ loop.shared.views = (function(_, l10n) {
|
|||||||
React.createElement("div", {className: "conversation"},
|
React.createElement("div", {className: "conversation"},
|
||||||
React.createElement("div", {className: "media nested"},
|
React.createElement("div", {className: "media nested"},
|
||||||
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
||||||
React.createElement("div", {className: "video_inner remote"})
|
React.createElement("div", {className: "video_inner remote remote-stream"})
|
||||||
),
|
),
|
||||||
React.createElement("div", {className: localStreamClasses})
|
React.createElement("div", {className: localStreamClasses})
|
||||||
),
|
),
|
||||||
|
@ -358,7 +358,7 @@ loop.shared.views = (function(_, l10n) {
|
|||||||
<div className="conversation">
|
<div className="conversation">
|
||||||
<div className="media nested">
|
<div className="media nested">
|
||||||
<div className="video_wrapper remote_wrapper">
|
<div className="video_wrapper remote_wrapper">
|
||||||
<div className="video_inner remote"></div>
|
<div className="video_inner remote remote-stream"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className={localStreamClasses}></div>
|
<div className={localStreamClasses}></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -251,7 +251,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||||
publisherConfig: this.getDefaultPublisherConfig({publishVideo: true}),
|
publisherConfig: this.getDefaultPublisherConfig({publishVideo: true}),
|
||||||
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
||||||
getRemoteElementFunc: this._getElement.bind(this, ".remote")
|
getRemoteElementFunc: this._getElement.bind(this, ".remote"),
|
||||||
|
getScreenShareElementFunc: this._getElement.bind(this, ".screen")
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +340,19 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
"local-stream-audio": this.state.videoMuted
|
"local-stream-audio": this.state.videoMuted
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var remoteStreamClasses = React.addons.classSet({
|
||||||
|
"video_inner": true,
|
||||||
|
"remote": true,
|
||||||
|
"remote-stream": true,
|
||||||
|
hide: this.state.receivingScreenShare
|
||||||
|
});
|
||||||
|
|
||||||
|
var screenShareStreamClasses = React.addons.classSet({
|
||||||
|
"screen": true,
|
||||||
|
"remote-stream": true,
|
||||||
|
hide: !this.state.receivingScreenShare
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
React.createElement("div", {className: "room-conversation-wrapper"},
|
React.createElement("div", {className: "room-conversation-wrapper"},
|
||||||
React.createElement("div", {className: "beta-logo"}),
|
React.createElement("div", {className: "beta-logo"}),
|
||||||
@ -357,11 +371,13 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
mozL10n.get("self_view_hidden_message")
|
mozL10n.get("self_view_hidden_message")
|
||||||
),
|
),
|
||||||
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
React.createElement("div", {className: "video_wrapper remote_wrapper"},
|
||||||
React.createElement("div", {className: "video_inner remote"})
|
React.createElement("div", {className: remoteStreamClasses}),
|
||||||
|
React.createElement("div", {className: screenShareStreamClasses})
|
||||||
),
|
),
|
||||||
React.createElement("div", {className: localStreamClasses})
|
React.createElement("div", {className: localStreamClasses})
|
||||||
),
|
),
|
||||||
React.createElement(sharedViews.ConversationToolbar, {
|
React.createElement(sharedViews.ConversationToolbar, {
|
||||||
|
dispatcher: this.props.dispatcher,
|
||||||
video: {enabled: !this.state.videoMuted,
|
video: {enabled: !this.state.videoMuted,
|
||||||
visible: this._roomIsActive()},
|
visible: this._roomIsActive()},
|
||||||
audio: {enabled: !this.state.audioMuted,
|
audio: {enabled: !this.state.audioMuted,
|
||||||
|
@ -251,7 +251,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||||
publisherConfig: this.getDefaultPublisherConfig({publishVideo: true}),
|
publisherConfig: this.getDefaultPublisherConfig({publishVideo: true}),
|
||||||
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
||||||
getRemoteElementFunc: this._getElement.bind(this, ".remote")
|
getRemoteElementFunc: this._getElement.bind(this, ".remote"),
|
||||||
|
getScreenShareElementFunc: this._getElement.bind(this, ".screen")
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +340,19 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
"local-stream-audio": this.state.videoMuted
|
"local-stream-audio": this.state.videoMuted
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var remoteStreamClasses = React.addons.classSet({
|
||||||
|
"video_inner": true,
|
||||||
|
"remote": true,
|
||||||
|
"remote-stream": true,
|
||||||
|
hide: this.state.receivingScreenShare
|
||||||
|
});
|
||||||
|
|
||||||
|
var screenShareStreamClasses = React.addons.classSet({
|
||||||
|
"screen": true,
|
||||||
|
"remote-stream": true,
|
||||||
|
hide: !this.state.receivingScreenShare
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="room-conversation-wrapper">
|
<div className="room-conversation-wrapper">
|
||||||
<div className="beta-logo" />
|
<div className="beta-logo" />
|
||||||
@ -357,11 +371,13 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||||||
{mozL10n.get("self_view_hidden_message")}
|
{mozL10n.get("self_view_hidden_message")}
|
||||||
</span>
|
</span>
|
||||||
<div className="video_wrapper remote_wrapper">
|
<div className="video_wrapper remote_wrapper">
|
||||||
<div className="video_inner remote"></div>
|
<div className={remoteStreamClasses}></div>
|
||||||
|
<div className={screenShareStreamClasses}></div>
|
||||||
</div>
|
</div>
|
||||||
<div className={localStreamClasses}></div>
|
<div className={localStreamClasses}></div>
|
||||||
</div>
|
</div>
|
||||||
<sharedViews.ConversationToolbar
|
<sharedViews.ConversationToolbar
|
||||||
|
dispatcher={this.props.dispatcher}
|
||||||
video={{enabled: !this.state.videoMuted,
|
video={{enabled: !this.state.videoMuted,
|
||||||
visible: this._roomIsActive()}}
|
visible: this._roomIsActive()}}
|
||||||
audio={{enabled: !this.state.audioMuted,
|
audio={{enabled: !this.state.audioMuted,
|
||||||
|
@ -14,6 +14,7 @@ FIREFOX_PREFERENCES = {
|
|||||||
"media.volume_scale": "0",
|
"media.volume_scale": "0",
|
||||||
"loop.gettingStarted.seen": True,
|
"loop.gettingStarted.seen": True,
|
||||||
"loop.seenToS": "seen",
|
"loop.seenToS": "seen",
|
||||||
|
"loop.screenshare.enabled": True,
|
||||||
|
|
||||||
# this dialog is fragile, and likely to introduce intermittent failures
|
# this dialog is fragile, and likely to introduce intermittent failures
|
||||||
"media.navigator.permission.disabled": True
|
"media.navigator.permission.disabled": True
|
||||||
|
@ -4,7 +4,6 @@ import urlparse
|
|||||||
from errors import NoSuchElementException, StaleElementException
|
from errors import NoSuchElementException, StaleElementException
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from wait import Wait
|
from wait import Wait
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -126,23 +125,32 @@ class Test1BrowserCall(MarionetteTestCase):
|
|||||||
join_button.click()
|
join_button.click()
|
||||||
|
|
||||||
# Assumes the standlone or the conversation window is selected first.
|
# Assumes the standlone or the conversation window is selected first.
|
||||||
def check_remote_video(self):
|
def check_video(self, selector):
|
||||||
video_wrapper = self.wait_for_element_displayed(
|
video_wrapper = self.wait_for_element_displayed(By.CSS_SELECTOR,
|
||||||
By.CSS_SELECTOR,
|
selector, 20)
|
||||||
".media .OT_subscriber .OT_widget-container", 20)
|
video = self.wait_for_subelement_displayed(video_wrapper,
|
||||||
video = self.wait_for_subelement_displayed(
|
By.TAG_NAME, "video")
|
||||||
video_wrapper, By.TAG_NAME, "video")
|
|
||||||
|
|
||||||
self.wait_for_element_attribute_to_be_false(video, "paused")
|
self.wait_for_element_attribute_to_be_false(video, "paused")
|
||||||
self.assertEqual(video.get_attribute("ended"), "false")
|
self.assertEqual(video.get_attribute("ended"), "false")
|
||||||
|
|
||||||
def standalone_check_remote_video(self):
|
def standalone_check_remote_video(self):
|
||||||
self.switch_to_standalone()
|
self.switch_to_standalone()
|
||||||
self.check_remote_video()
|
self.check_video(".remote .OT_subscriber .OT_widget-container")
|
||||||
|
|
||||||
def local_check_remote_video(self):
|
def local_check_remote_video(self):
|
||||||
self.switch_to_chatbox()
|
self.switch_to_chatbox()
|
||||||
self.check_remote_video()
|
self.check_video(".remote .OT_subscriber .OT_widget-container")
|
||||||
|
|
||||||
|
def local_enable_screenshare(self):
|
||||||
|
self.switch_to_chatbox()
|
||||||
|
button = self.marionette.find_element(By.CLASS_NAME, "btn-screen-share")
|
||||||
|
|
||||||
|
button.click()
|
||||||
|
|
||||||
|
def standalone_check_remote_screenshare(self):
|
||||||
|
self.switch_to_standalone()
|
||||||
|
self.check_video(".media .screen .OT_subscriber .OT_widget-container")
|
||||||
|
|
||||||
def local_leave_room_and_verify_feedback(self):
|
def local_leave_room_and_verify_feedback(self):
|
||||||
button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup")
|
button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup")
|
||||||
@ -170,6 +178,11 @@ class Test1BrowserCall(MarionetteTestCase):
|
|||||||
self.standalone_check_remote_video()
|
self.standalone_check_remote_video()
|
||||||
self.local_check_remote_video()
|
self.local_check_remote_video()
|
||||||
|
|
||||||
|
# XXX To enable this, we either need to navigate the permissions prompt
|
||||||
|
# or have a route where we don't need the permissions prompt.
|
||||||
|
# self.local_enable_screenshare()
|
||||||
|
# self.standalone_check_remote_screenshare()
|
||||||
|
|
||||||
# hangup the call
|
# hangup the call
|
||||||
self.local_leave_room_and_verify_feedback()
|
self.local_leave_room_and_verify_feedback()
|
||||||
|
|
||||||
|
@ -657,6 +657,16 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#receivingScreenShare", function() {
|
||||||
|
it("should save the state", function() {
|
||||||
|
store.receivingScreenShare(new sharedActions.ReceivingScreenShare({
|
||||||
|
receiving: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(store.getStoreState().receivingScreenShare).eql(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("#remotePeerConnected", function() {
|
describe("#remotePeerConnected", function() {
|
||||||
it("should set the state to `HAS_PARTICIPANTS`", function() {
|
it("should set the state to `HAS_PARTICIPANTS`", function() {
|
||||||
store.remotePeerConnected();
|
store.remotePeerConnected();
|
||||||
|
@ -236,13 +236,15 @@ describe("loop.shared.mixins", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("Events", function() {
|
describe("Events", function() {
|
||||||
var localElement, remoteElement;
|
var localElement, remoteElement, screenShareElement;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
sandbox.stub(view, "getDOMNode").returns({
|
sandbox.stub(view, "getDOMNode").returns({
|
||||||
querySelector: function(classSelector) {
|
querySelector: function(classSelector) {
|
||||||
if (classSelector.contains("local")) {
|
if (classSelector.contains("local")) {
|
||||||
return localElement;
|
return localElement;
|
||||||
|
} else if (classSelector.contains("screen")) {
|
||||||
|
return screenShareElement;
|
||||||
}
|
}
|
||||||
return remoteElement;
|
return remoteElement;
|
||||||
}
|
}
|
||||||
@ -275,6 +277,19 @@ describe("loop.shared.mixins", function() {
|
|||||||
|
|
||||||
expect(remoteElement.style.height).eql("100%");
|
expect(remoteElement.style.height).eql("100%");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should update the height on the screen share stream element", function() {
|
||||||
|
screenShareElement = {
|
||||||
|
offsetWidth: 100,
|
||||||
|
offsetHeight: 100,
|
||||||
|
style: { height: "0%" }
|
||||||
|
};
|
||||||
|
|
||||||
|
rootObject.events.resize();
|
||||||
|
sandbox.clock.tick(10);
|
||||||
|
|
||||||
|
expect(screenShareElement.style.height).eql("100%");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("orientationchange", function() {
|
describe("orientationchange", function() {
|
||||||
@ -303,6 +318,19 @@ describe("loop.shared.mixins", function() {
|
|||||||
|
|
||||||
expect(remoteElement.style.height).eql("100%");
|
expect(remoteElement.style.height).eql("100%");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should update the height on the screen share stream element", function() {
|
||||||
|
screenShareElement = {
|
||||||
|
offsetWidth: 100,
|
||||||
|
offsetHeight: 100,
|
||||||
|
style: { height: "0%" }
|
||||||
|
};
|
||||||
|
|
||||||
|
rootObject.events.orientationchange();
|
||||||
|
sandbox.clock.tick(10);
|
||||||
|
|
||||||
|
expect(screenShareElement.style.height).eql("100%");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,13 +12,15 @@ describe("loop.OTSdkDriver", function () {
|
|||||||
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
|
||||||
var sandbox;
|
var sandbox;
|
||||||
var dispatcher, driver, publisher, sdk, session, sessionData;
|
var dispatcher, driver, publisher, sdk, session, sessionData;
|
||||||
var fakeLocalElement, fakeRemoteElement, publisherConfig, fakeEvent;
|
var fakeLocalElement, fakeRemoteElement, fakeScreenElement;
|
||||||
|
var publisherConfig, fakeEvent;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
sandbox = sinon.sandbox.create();
|
sandbox = sinon.sandbox.create();
|
||||||
|
|
||||||
fakeLocalElement = {fake: 1};
|
fakeLocalElement = {fake: 1};
|
||||||
fakeRemoteElement = {fake: 2};
|
fakeRemoteElement = {fake: 2};
|
||||||
|
fakeScreenElement = {fake: 3};
|
||||||
fakeEvent = {
|
fakeEvent = {
|
||||||
preventDefault: sinon.stub()
|
preventDefault: sinon.stub()
|
||||||
};
|
};
|
||||||
@ -290,6 +292,7 @@ describe("loop.OTSdkDriver", function () {
|
|||||||
|
|
||||||
dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||||
getLocalElementFunc: function() {return fakeLocalElement;},
|
getLocalElementFunc: function() {return fakeLocalElement;},
|
||||||
|
getScreenShareElementFunc: function() {return fakeScreenElement;},
|
||||||
getRemoteElementFunc: function() {return fakeRemoteElement;},
|
getRemoteElementFunc: function() {return fakeRemoteElement;},
|
||||||
publisherConfig: publisherConfig
|
publisherConfig: publisherConfig
|
||||||
}));
|
}));
|
||||||
@ -353,16 +356,50 @@ describe("loop.OTSdkDriver", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("streamCreated", function() {
|
describe("streamCreated (publisher/local)", function() {
|
||||||
|
it("should dispatch a VideoDimensionsChanged action", function() {
|
||||||
|
var fakeStream = {
|
||||||
|
hasVideo: true,
|
||||||
|
videoType: "camera",
|
||||||
|
videoDimensions: {width: 1, height: 2}
|
||||||
|
};
|
||||||
|
|
||||||
|
publisher.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||||
|
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||||
|
new sharedActions.VideoDimensionsChanged({
|
||||||
|
isLocal: true,
|
||||||
|
videoType: "camera",
|
||||||
|
dimensions: {width: 1, height: 2}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("streamCreated (session/remote)", function() {
|
||||||
var fakeStream;
|
var fakeStream;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
fakeStream = {
|
fakeStream = {
|
||||||
fakeStream: 3
|
hasVideo: true,
|
||||||
|
videoType: "camera",
|
||||||
|
videoDimensions: {width: 1, height: 2}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should subscribe to the stream", function() {
|
it("should dispatch a VideoDimensionsChanged action", function() {
|
||||||
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||||
|
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||||
|
new sharedActions.VideoDimensionsChanged({
|
||||||
|
isLocal: false,
|
||||||
|
videoType: "camera",
|
||||||
|
dimensions: {width: 1, height: 2}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should subscribe to a camera stream", function() {
|
||||||
session.trigger("streamCreated", {stream: fakeStream});
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
sinon.assert.calledOnce(session.subscribe);
|
sinon.assert.calledOnce(session.subscribe);
|
||||||
@ -370,15 +407,85 @@ describe("loop.OTSdkDriver", function () {
|
|||||||
fakeStream, fakeRemoteElement, publisherConfig);
|
fakeStream, fakeRemoteElement, publisherConfig);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should subscribe to a screen sharing stream", function() {
|
||||||
|
fakeStream.videoType = "screen";
|
||||||
|
|
||||||
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(session.subscribe);
|
||||||
|
sinon.assert.calledWithExactly(session.subscribe,
|
||||||
|
fakeStream, fakeScreenElement, publisherConfig);
|
||||||
|
});
|
||||||
|
|
||||||
it("should dispach a mediaConnected action if both streams are up", function() {
|
it("should dispach a mediaConnected action if both streams are up", function() {
|
||||||
driver._publishedLocalStream = true;
|
driver._publishedLocalStream = true;
|
||||||
|
|
||||||
session.trigger("streamCreated", {stream: fakeStream});
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
// Called twice due to the VideoDimensionsChanged above.
|
||||||
|
sinon.assert.calledTwice(dispatcher.dispatch);
|
||||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||||
sinon.match.hasOwn("name", "mediaConnected"));
|
sinon.match.hasOwn("name", "mediaConnected"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not dispatch a mediaConnected action for screen sharing streams",
|
||||||
|
function() {
|
||||||
|
driver._publishedLocalStream = true;
|
||||||
|
fakeStream.videoType = "screen";
|
||||||
|
|
||||||
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.neverCalledWithMatch(dispatcher.dispatch,
|
||||||
|
sinon.match.hasOwn("name", "mediaConnected"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not dispatch a ReceivingScreenShare action for camera streams",
|
||||||
|
function() {
|
||||||
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.neverCalledWithMatch(dispatcher.dispatch,
|
||||||
|
new sharedActions.ReceivingScreenShare({receiving: true}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch a ReceivingScreenShare action for screen sharing streams",
|
||||||
|
function() {
|
||||||
|
fakeStream.videoType = "screen";
|
||||||
|
|
||||||
|
session.trigger("streamCreated", {stream: fakeStream});
|
||||||
|
|
||||||
|
// Called twice due to the VideoDimensionsChanged above.
|
||||||
|
sinon.assert.calledTwice(dispatcher.dispatch);
|
||||||
|
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||||
|
new sharedActions.ReceivingScreenShare({receiving: true}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("streamDestroyed", function() {
|
||||||
|
var fakeStream;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
fakeStream = {
|
||||||
|
videoType: "screen"
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch a ReceivingScreenShare action", function() {
|
||||||
|
session.trigger("streamDestroyed", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||||
|
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||||
|
new sharedActions.ReceivingScreenShare({
|
||||||
|
receiving: false
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not dispatch an action if the videoType is camera", function() {
|
||||||
|
fakeStream.videoType = "camera";
|
||||||
|
|
||||||
|
session.trigger("streamDestroyed", {stream: fakeStream});
|
||||||
|
|
||||||
|
sinon.assert.notCalled(dispatcher.dispatch);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("streamPropertyChanged", function() {
|
describe("streamPropertyChanged", function() {
|
||||||
@ -415,8 +522,8 @@ describe("loop.OTSdkDriver", function () {
|
|||||||
|
|
||||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||||
sinon.match.hasOwn("name", "videoDimensionsChanged"))
|
sinon.match.hasOwn("name", "videoDimensionsChanged"));
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("connectionCreated", function() {
|
describe("connectionCreated", function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user