Record a video for Allure in Playwright - playwright

How can I record a video and it will be attached to allure like trace or screenshot?
use: {
actionTimeout: 0,
trace: 'on',
screenshot: 'on',
viewport: {width:1920, height: 1080},
video: 'on',
},
that's what I have in playwright.config.ts and video is only one what is NOT working.

According to the documentation, you have to specify the dir property of recordVideo context option. Otherwise videos are not recorded. Thus, your configuration file should look like this:
use = {
actionTimeout: 0,
trace: 'on',
screenshot: 'on',
viewport: { width: 1920, height: 1080 },
video: 'on',
contextOptions: {
recordVideo: {
dir: './output' // Or wherever you want the videos to be saved.
}
}
}
Also, you can specify the record video directory on page level.
Don't forget to call browserContext.close() at the end of your tests, for the videos to be successfully saved. Personally, I do it in test.afterAll() hook.
EDIT: There is an open issue regarding some config options not working as expected, including the video one. On the first comment, one of the developers states that "Video does not work in this case, that's a known issue.". Maybe you can skip the video option completely - I guess it will still work.
EDIT2: To attach the video recording to Allure reporter, include the following code in test.afterAll() hook:
test.afterAll(async ({ }, testInfo) => {
await context.close() // Required for successful save of video recording.
const path = await page.video().path()
await testInfo.attach('video', {
path,
contentType: 'video/webm',
})
})

for playwright with allure report
After(async function (this: ICustomWorld, { result, pickle }: ITestCaseHookParameter) {
...
await this.page?.close();
await this.context?.close();
...
const buffer = fs.readFileSync(videoPath);
await this.attach(buffer, 'video/webm');
});
video will be attached, it is shown as a link attachment, when click on it - open in the next tab video with scenario run

Related

How to restore default window size in an electron app?

Is there a way to restore main window in an electron app to a certain size? To explain what I am trying to accomplish, let me give you an example:
When I open Windows Explorer, it opens with a certain size and at a certain position. Then I maximize that window and close the explorer. Next time when I restart the explorer, it opens in the same state as when I closed it i.e. in maximized state. However when I click on the restore button, explorer restores to the width/height and position before it was maximized.
I would like to accomplish the same in my electron application as well. However that is not happening.
What I am doing is when my application closes, I capture the dimensions (width, height) and position (x, y coordinates) of the application window using (win.getBounds())and save those in a config file using electron-config. This is what my code looks like:
const Config = require('electron-config')
const config = new Config();
mainWindow.on('close', () => {
config.set('winBounds', mainWindow.getBounds())
});
Now when I start the application, I read the settings from the config file (actually electron-config does that for me) and use that to set the initial dimensions/position of the window. I am using code like below:
let opts = {
show: false,
icon: path.join(__dirname, 'app-window-icon.png')
};
Object.assign(opts, config.get('winBounds'));
mainWindow = new BrowserWindow(opts);
This is also working great. However the only option I get now is maximize the window. I'm not able to find any option to restore the window to a size before it was maximized.
For example, let's say the user launches the application with 1024x768 px dimensions. User then maximizes the application window and then closes it. When the user relaunches the application, it opens with the size it was closed and the only option I see is to maximize the window. What I am looking for is an option to restore the window size to 1024x768px.
I looked up the documentation here: https://github.com/electron/electron/blob/master/docs/api/browser-window.md but unfortunately couldn't find anything there.
I used the solution here which involves persisting your windows size and position in electron-settings and it works perfectly.
Include the windowStateKeeper function in your code and then adapt your createMainWindow function as follows:
function createMainWindow() {
const mainWindowStateKeeper = windowStateKeeper('main');
const win = new electron.BrowserWindow({
title: 'main',
x: mainWindowStateKeeper.x,
y: mainWindowStateKeeper.y,
width: mainWindowStateKeeper.width,
height: mainWindowStateKeeper.height
});
mainWindowStateKeeper.track(win);
win.loadURL(`file://${__dirname}/index.html`);
win.on('closed', onClosed);
return win;
}
Here is complete solution:
stateKeeper.ts:
import {screen} from 'electron';
import settings from 'electron-settings';
export const windowStateKeeper = async (windowName) => {
let window, windowState;
const setBounds = async () => {
// Restore from appConfig
if (await settings.has(`windowState.${windowName}`)) {
windowState = await settings.get(`windowState.${windowName}`);
return;
}
const size = screen.getPrimaryDisplay().workAreaSize;
// Default
windowState = {
x: undefined,
y: undefined,
width: size.width / 2,
height: size.height / 2,
};
};
const saveState = async () => {
// bug: lots of save state events are called. they should be debounced
if (!windowState.isMaximized) {
windowState = window.getBounds();
}
windowState.isMaximized = window.isMaximized();
await settings.set(`windowState.${windowName}`, windowState);
};
const track = async (win) => {
window = win;
['resize', 'move', 'close'].forEach((event) => {
win.on(event, saveState);
});
};
await setBounds();
return {
x: windowState.x,
y: windowState.y,
width: windowState.width,
height: windowState.height,
isMaximized: windowState.isMaximized,
track,
};
};
main.ts
import {windowStateKeeper} from './utils/windowStateKeeper';
const mainWindowStateKeeper = await windowStateKeeper('main');
// Create the browser window.
mainWin = new BrowserWindow({
title: 'Desktop',
x: mainWindowStateKeeper.x,
y: mainWindowStateKeeper.y,
width: mainWindowStateKeeper.width,
height: mainWindowStateKeeper.height,
webPreferences: {
nodeIntegration: true,
allowRunningInsecureContent: serve ? true : false,
contextIsolation: false, // false if you want to run e2e test with Spectron
enableRemoteModule: true, // true if you want to run e2e test with Spectron or use remote module in renderer context (ie. Angular)
},
});
// Track window state
mainWindowStateKeeper.track(mainWin);
I implemented this after a lot of testing this is the most accurate and simple solution to remember window properties.
i used electron-store to store values, you can use any storage methods you like.
main.js
let windowConfig = {
width: 1280,
height: 680,
}
function createWindow() {
Object.assign(windowConfig, CONFIG.get("winBounds"))
mainWindow = new BrowserWindow(windowConfig)
if (windowConfig.isMaximized) {
mainWindow.maximize()
}
mainWindow.on("close", () => {
Object.assign(windowConfig, {
isMaximized: mainWindow.isMaximized()
}, mainWindow.getNormalBounds())
CONFIG.set("winBounds", windowConfig) // saves window's properties using electron-store
})
}

Is it possible to link to a 360 YouTube video with ReactVR?

In the documentation for ReactVR for VideoPano
it demonstrates pointing to a video in the code base.
Is it possible to link to an external link (aka Youtube)?
So instead of video.mp4, it would link to https://www.youtube.com/watch?v=hkgYIr_LWPw&index=1&list=PL-BE7kqSgbEj44peyt5BmLK63kbDp7Rhu
let videoUrl = 'video.webm';
const supportedFormats = NativeModules.VideoModule.supportedFormats;
for (let i = 0; i < supportedFormats.length; i++) {
if (supportedFormats[i] === 'mp4') {
videoUrl = 'video.mp4';
}
}
the rest of the code looks like this.
class WelcomeToVR extends React.Component {
constructor(props) {
super(props);
this.state = {
playerState: new MediaPlayerState({autoPlay: true, muted: true}), // init with muted, autoPlay
};
}
render() {
return (
<View>
<VideoPano
playerState={this.state.playerState}
source={asset(videoUrl, {layout: 'SPHERE'})}
/>
<VideoControl
style={{
height: 0.2,
width: 4,
layoutOrigin: [0.5, 0.5, 0],
transform: [{translate: [0, 0, -4]}],
}}
playerState={this.state.playerState}
Solution 1 (didn't work)
You could try to use an embed the video: https://www.youtube.com/embed/hkgYIr_LWPw. This will give you just the video without other content.
If you need a embedded video, just left click on the video and choose "embed this video" and change the source of your
<VideoPano playerState={this.state.playerState} source={videoUrl} />
Not sure if this could wok because the source code is again HTML, JS and CSS. But you could give it a try. And it didn't work
Solution 2
Download the video using a YouTube downloader1 or other one and use that.
<VideoPano playerState={this.state.playerState}
source={ asset(videoUrl, { layout: 'SPHERE' }) } />
1 No publicity for that tool, just the first result I've found on Google.
YouTube intentionally chooses to obfuscate the direct links to their video files. Linking the embedded player isn't a solution since that thing's a mini web app with streaming logic, not an actual video file.
There's a pretty good write-up on how you could get around that here How do all of these “Save video from YouTube” services work? (probably against their Terms and Conditions though).
It is possible, however, to link to an external video URL, here's how:
Pick a random 3D 360 YouTube video, like this one
Download it, I used savefrom.net but there are many others and host it somewhere http://YOURDOMAIN/YOURVIDEO.mp4
Render a <VideoPano /> in your scene/view
<VideoPano source={{
uri: 'http://YOURDOMAIN/YOURVIDEO.mp4',
stereo: 'BOTTOM_TOP_3D' // this is specific to YouTube 3D videos
}} />
https://facebook.github.io/react-vr/docs/videopano.html

JW Player not showing flash mode and also showing no player controls on an Asp.Net MVC view

I am using jwPlayer 6.8 on a View in my Asp.Net MVC application.
I am using following javascript code for streaming a video on player:
var el = document.getElementById("player");
var player = jwplayer(el).setup({
file: "W-UNIT1",
streamer: "rtmp://my-server/live",
type: "rtmp",
width: 383,
height: 300,
controls: true,
primary: "flash",
modes: [
{ type: "flash", src: '/jwPlayer68/jwplayer.flash.swf' },
{ type: "html5" }
],
events: {
onReady: function () {
player.play();
}
}
});
The player plays video fine but if I right click on player surface it shows me regular window's context menu but not flash menu like Settings, Global Settings etc.
Also no controls appear on player like mute, play/pause etc.
Current version I am using is version 6.8. My browser is Firefox version 27.0.1
What am I missing?
you are using Jwplayer 6.8, then try using below setup instead of your.
jwplayer("myElement").setup({
playlist: [{
image: "/assets/myVideo.jpg",
sources: [{
file: "rtmp://example.com/application/mp4:myVideo.mp4"
},{
file: "/assets/myVideo.mp4"
}]
}],
height: 360,
primary: "flash",
width: 640
});
I think your setup is following old jwplayer parameters.
Jwplayer have guide for this here
Using RTMP streaming
RTMP single stream
Helpful Stackoverflow questions :
how-do-i-play-rtmp-streams-with-jw-player
streaming-with-cloudfront-to-jwplayer
using-dynamic-smil-file-with-jw-player
It seems like I have once again found answer to my own raised question.
Issue is neither related to rtmp streaming nor is specific to any specific version of JW Player. In fact it occurs not only on newer versions plus older versions.
It was occurring because of some custom css of mine, applied onto the JW Player HTML div container. For some reason I was overriding its CSS in my Asp.Net View and it was causing this issue.
My example code:
HTML:
<body>
<script src="http://jwpsrv.com/library/bfifOqXfEeOr_yIACi0I_Q.js"></script>
<div id="player"></div>
</body>
Javascript:
$(function() {
var el = document.getElementById("player");
var player = jwplayer(el).setup({
file: "http://techslides.com/demos/sample-videos/small.mp4",
width: 383,
height: 300,
controls: true,
events: {
onReady: function () {
player.play();
}
}
});
});
CSS:
div[id^=player_]
{
/* Comment this css for correct working of jwplayer */
min-width:383px !important;
min-height:300px !important;
}
Here is the jsFiddle for this:
http://jsfiddle.net/QCyzh/2/

Remove YouTube related videos in this script

I have seen this script to auto-mute video's from youtube embedded on a site:
How do I automatically play a Youtube video (IFrame API) muted?
The code is available on fiddle:
http://jsfiddle.net/9RjzU/3/
However I would like to know what to add to this code to prevent related videos appearing?
Thanks
Azzam
In your situation, all that is needed is to add 'rel': 0 to the PlayerVars parameters, like so:
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
playerVars: {
'autoplay': 1,
'controls': 1,
'autohide': 1,
'wmode': 'opaque',
'rel': 0
},
videoId: 'JW5meKfy3fY',
events: { 'onReady': onPlayerReady }
});
}
You might also be interested in the full list of parameters available for the YouTube iframe API, found here: https://developers.google.com/youtube/player_parameters#Parameters

Making a panel only available for certain URLs

Chrome has something called "Page Actions", and I'm roughly trying to replicate that functionality with the Firefox Addon SDK/Jetpack. There's probably a better approach than what I've tried so far, and I'm open to suggestions.
Using tabs, I'm able to listen for tab ready and activate events, and if the tab's URL matches, the addon widget should be enabled; if not, disabled. I've got to the point where I can change the icon when appropriate, but I'd like to disable the panel as well.
Strategy 1: Steal the click event and only show the panel if we're on the right page; otherwise, ignore. Problem is, according to the docs, manually showing the panel causes it not to be anchored, a bug that's not had much progress on it.
Strategy 2: Set the contentURL to null when disabling. Get an error whining about it not being an URL.
Strategy 3: Use a different HTML document for the disabled state. Setting panel.contentURL to another URL doesn't work after going to a different page?
Here's the code:
const widgets = require("widget");
const Panel = require("panel").Panel;
const tabs = require("tabs");
const data = require("self").data;
const prefs = require("simple-prefs").prefs;
var panel = Panel({
width: 480,
height: 640,
contentURL: data.url("panel.html"),
contentScriptFile: [data.url('jquery.min.js'), data.url('panel.js')],
onMessage: function (msg) { console.log(msg) }
});
var widget = widgets.Widget({
id: "icon",
label: "Export",
contentURL: data.url("icon.png"),
panel: panel
});
function enable() {
widget.contentURL = data.url('icon.png');
panel.contentURL = data.url("panel.html");
}
function disable() {
widget.contentURL = data.url('icon_disabled.png');
panel.contentURL = data.url("panel_disabled.html");
}
function on_change_tab(tab) {
console.log(tab.url);
if (/http:\/\/example.com\/.*/.exec(tab.url)) {
console.log('ENABLE');
enable();
} else {
console.log('DISABLE');
disable();
}
console.log(panel.contentURL);
}
tabs.on('ready', on_change_tab);
tabs.on('activate', on_change_tab);
Related, but should have the anchoring problem? How to reload a widget popup panel with firefox addon sdk?
In case you still haven't solved your issue (and for anyone else having a similar problem):
I had a similar issue and resolved it by using erikvold's ToolbarButton package. Once you've installed that and its dependencies, something like this in your main.js file should work.
var pan = require("panel").Panel({
width: 400,
height: 600,
contentURL: "http://stackoverflow.com"
//maybe some more options here
});
var button = require("toolbarbutton").ToolbarButton({
id: "myButton",
label: "My Button",
image: data.url("someicon.png"),
panel: pan //This binds the panel to this toolbarbutton
});
I hope you can find some way to adapt this to your project.
toolbarbutton.ToolbarButton({
id: "MyAddon",
label: "My Addon",
tooltiptext: "My Addon Tooltip",
image: data.url("logo.png"),
onCommand: function() {
var dictionary_panel = require("panel").Panel({
width:630,
height:600,
contentURL: data.url("HtmlPage.html"),
contentScriptWhen: 'ready',
contentScriptFile: [data.url("style.css"),data.url("jquery-1.7.1.js"),
data.url("javascriptquezz.js"),data.url("create.js")]
});
dictionary_panel.show();
}
});

Resources