Can't check if the "Extension installed" page was opened - puppeteer

I have an extension, which has a listener for the chrome.runtime.onInstalled event, that opens a new page when the extension is installed. I can see it happening in regular Chrome and in puppeteer also, using the config below:
browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`
]
})
page = await browser.newPage()
await page.setViewport({
width: config.viewport.width,
height: config.viewport.height
})
But I can't seem to get the data for this new tab, which should be returned by this command:
let pages = await browser.targets()
pages.forEach( (v, i) => {
console.log(i, v._targetInfo)
})
Which only returns this:
console.log test/installedExtension.test.js:49
0 { targetId: '2E60BA3854355C415D48D89AA65727BC',
type: 'page',
title: '',
url: 'about:blank',
attached: false,
browserContextId: '11F90429E632C8BC5C0073B1B74D0497' }
console.log test/installedExtension.test.js:49
1 { targetId: '416b3c97-04e7-4042-9401-d5ea7880bf22',
type: 'browser',
title: '',
url: '',
attached: true }
console.log test/installedExtension.test.js:49
2 { targetId: 'A8AA1B73923E934D284BD65CBF779956',
type: 'background_page',
title: 'Some Random Title',
url:
'chrome-extension://kmendfapggjehodndflmmgagdbamhnfd/_generated_background_page.html',
attached: false,
browserContextId: '11F90429E632C8BC5C0073B1B74D0497' }
console.log test/installedExtension.test.js:49
3 { targetId: '0A42832C4BD6539557765E8E99F113ED',
type: 'background_page',
title: 'My Extension Title',
url:
'chrome-extension://kpepplbhmfgaiibhacpojdokimblkbnh/src/background.html',
attached: false,
browserContextId: '11F90429E632C8BC5C0073B1B74D0497' }
console.log test/installedExtension.test.js:49
4 { targetId: 'C5B3440C60F001E559B01F364093F6CF',
type: 'page',
title: '',
url: 'about:blank',
attached: true,
browserContextId: '11F90429E632C8BC5C0073B1B74D0497' }
Although it brings me the info about the extension's background HTML, I need to get the opened tab, to do some assertions.
Does anybody have any ideas on this matter?

Related

Can't get speaker + microphone audio working with chrome.desktopCapture and RecortRTC

I am trying to build a chrome extension that captures a users screen with their speaker audio (computer audio) and their microphone audio. Using the examples from RecordRTC I have pieced the below together, however when I open the recorded .webm file I am unable to hear any sounds at all.
Is there something else I should be doing to get audio?
Below is the code for my background script with some sections removed to make it more clear. When someone clicks the start record button, the startRecording() function is called.
const OPTIONS = {
type: 'video',
disableLogs: false,
mimeType: 'video/webm'
}
const captureUserMedia = callback => {
chrome.desktopCapture.chooseDesktopMedia(['screen', 'window', 'audio'], chromeMediaSourceId => {
const options = {
audio: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: chromeMediaSourceId,
echoCancellation: true
},
optional: []
},
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: chromeMediaSourceId
},
optional: []
}
};
navigator.mediaDevices.getUserMedia(options)
.then(callback)
.catch(err => new Error(err));
});
};
const startRecording = () => {
captureUserMedia(mediaStream => {
state.recordData = RecordRTC(mediaStream, OPTIONS);
state.mediaStream = mediaStream;
state.recordData.startRecording();
});
}
const stopRecording = () => {
state.recordData.stopRecording(function(videoURL) {
chrome.tabs.create({ url: 'show-video.html?video=' + videoURL });
});
state.mediaStream.getTracks().forEach(track => track.stop());
}
Apparently this is not a bug and an issue with MacOS itself. Chrome are aware of it but don't seem to have any plans to fix it: bugs.chromium.org/issue/603259

Setting Stormpath Configuration Options

I am trying to customize the registration page with Stormpath and I can't figure out why the configuration options are not working. The enableXXX and requireXXX work, but none of the info inside web:{...} is showing up. I've tried reordering the options, but that doesn't work either.
Specifically, I want to:
-- Register users at /signup instead of /register. Right now only /register is working.
-- I want to redirect them to another site after registration. I randomly put google.com in there, but I'm still redirected to "/" after registration is complete.
-- I want to reorder the registration fields. I want email to be the first field, but username is currently first.
Here's app.js:
// Import required modules.
var express = require('express');
var stormpath = require('express-stormpath');
var path = require('path');
var engine = require('ejs-mate');
var app = express();
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
// Configure public views
app.set('views','./views');
app.use(stormpath.init(app, {
apiKeyFile: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + ~removed
secretKey: '~removed',
application: '~removed',
enableRegistration: true,
enableGivenName: false,
requireGivenName: false,
enableSurname: false,
requireSurname: false,
website: true,
api: true,
web: {
register: {
uri: '/signup', // Use a different URL
nextUri: 'http://google.com', // Where to send the user to, if auto login is enabled
fields: {
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: [ "email", "username", "password", "passwordConfirm" ],
}
},
enableUsername: true,
requireUsername: true,
enableConfirmPassword: true,
requireConfirmPassword: true
}
));
app.get('/', function(req, res) {
res.render('home.ejs', {
title: 'Welcome'
});
});
app.get('/', function(req, res) {
res.send('home page!');
});
app.listen(process.env.PORT || 3000);
Other possibly relevant info:
-- The site is hosted on Heroku, but I'm not using the Stormpath add-on because I couldn't get it to work.
-- I'm on a Mac.
I've been stuck on this for days and I haven't been able to figure out what I'm doing wrong. Any help would be much appreciated.
The issue is likely this: we released a new version of this library recently which has new configuration options, and it appears you are using our OLD docs as a reference.
Here's what you'll want to do:
Update to the latest express-stormpath release. Then use the code below: (I converted your example to work with the latest release):
app.use(stormpath.init(app, {
client: {
apiKey: {
file: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + '~removed'
}
},
application: {
href: '~removed',
},
web: {
register: {
enabled: true,
uri: '/signup',
nextUri: 'http://google.com', // don't send them here =)
fields: {
username: {
enabled: true,
required: true
},
givenName: {
enabled: false,
required: false
},
surname: {
enabled: false,
required: false
},
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: ['username', 'email', 'password', 'passwordConfirm']
}
},
website: true,
api: true
}));

AngularJS - Multiple StateParems

We are still picking up and learning AngularJS but can't seem to figure this issue out, we want to be able to select a product type and use the formData value ("productType":"1") image1 to display the correct JSON product data related to this ID image2.
These are our controllers below within app.js, we have tried using multiple $stateParems but cant get seem to get the producttype id working with the stateParems.
Each productType ID is related to its own JSONstub, this is what we are using currently but this only grabs the jobID and not the producttype id below.
$scope.productid = $stateParams.jobID[0];
url: 'http://jsonstub.com/producttype/' + $scope.productid,
Here is our Plnkr, to find the Product Type section Click 'Login' > 'CHD24 - 26384108' 'View' > Next.
If anyone could advice and point us in the right direction this would help massively, also as we are new to AngularJS if you see anything else that we are doing wrongly please point it out.
Thank you.
// Product Type
.controller('warrantyCtrl', function($scope, $http, $stateParams) {
$scope.params = $stateParams.jobID[0];
$scope.dataLoaded = false;
$http({
url: 'http://jsonstub.com/warranty/' + $scope.params,
method: 'GET',
dataType: 'json',
data: '',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://run.plnkr.co',
'JsonStub-User-Key': '1357f082-ea56-46f0-adc5-3e5c273f6f87',
'JsonStub-Project-Key': 'e4f971a2-db30-45a0-80f9-bfa41b922c64'
}
}).success(function(data, status, headers, config) {
$scope.warrantydata = data;
$scope.dataLoaded = true;
}).error(function(data, status, error, config) {
$scope.warrantydata = [{
heading: "Error",
description: "Could not load json data"
}];
$scope.dataLoaded = false;
});
$scope.formData = {
'jobID': $scope.params
};
// Product Type Select
$scope.products = [{
id: '1',
name: 'Petrol Lawnmower'
}, {
id: '2',
name: 'Electric Lawnmower'
}, {
id: '3',
name: 'Petrol Chainsaw'
}, {
id: '4',
name: 'Electric Chainsaw'
}, {
id: '5',
name: 'Petrol Timmer'
}, {
id: '6',
name: 'Electric Timmer'
}, {
id: '7',
name: 'Etc'
}];
})
// Product Data
.controller('warrantyFormProductType', function($scope, $http, $stateParams) {
$scope.productid = $stateParams.jobID[0];
$http({
url: 'http://jsonstub.com/producttype/' + $scope.productid, // This needs to be productType id
method: 'GET',
dataType: 'json',
data: '',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://run.plnkr.co',
'JsonStub-User-Key': '1357f082-ea56-46f0-adc5-3e5c273f6f87',
'JsonStub-Project-Key': 'e4f971a2-db30-45a0-80f9-bfa41b922c64'
}
}).success(function(data, status, headers, config) {
$scope.productdata = data;
}).error(function(data, status, error, config) {
$scope.productdata = [{
heading: "Error",
description: "Could not load json data"
}];
})
// Add / Remove Columns (Still working on)
$scope.removeRow = function(index) {
$scope.productdata.splice(index, 1);
if ($scope.productdata.length() === 0) {
$scope.productdata = [];
}
};
$scope.addRow = function() {
var newrow = [];
if ($scope.productdata.length === 0) {
newrow = [{
'en': ''
}];
} else {
$scope.productdata[0].forEach(function(row) {
newrow.push({
'en': ''
});
});
}
$scope.productdata.push(newrow);
};
});
Is your API request supposed to be like this http://jsonstub.com/2/1 ?
Assuming yes, I've updated the code here
But I am getting Error 400 for this request.
Take a look and comment if this is what you needed.

ExtJS ComboBox dynamic JSON updates

I have found numerous issues explaining why the JSON store is not updated in an Ext JS comboBox.
We have made a re-usable ExtJS combobox control, this is the source code for it.
Ext.define('ReusableComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.Reusablecombobox',
queryMode: 'local',
forceSelection: true,
valueField: 'id',
displayField: 'displayField',
autoLoad: false,
initComponent: function () {
if (!this.store) {
var store = Ext.create('Ext.data.Store', {
autoLoad: this.autoLoad,
fields:['id', 'displayField', 'Id', 'Code', 'Description', 'IsIncluded', 'IsActive'],
proxy: {
type: 'ajax',
url: urlContent('validurl/getcodes'),
reader: {
type: 'json',
root: 'data'
}
}
});
store.on('load', this.handler_StoreLoad, this);
Ext.apply(this, {
store: store
});
}
this.callParent();
},
handler_StoreLoad: function (store, records, successful, options) {
addFieldsToList(records, function (item) {
item.data['id'] = item.data.Id;
item.data['displayField'] = item.data.Code + ' | ' + item.data.Description;
});
},
addFieldsToList: function( list, buildDisplayFieldFunc ){
if( list ){
for( var i=0, j=list.length; i<j; i++ ){
buildDisplayFieldFunc( list[i] );
}
return list;
}
}
});
When I dynamically add another item to the comboBox store, the comboBox does not refresh. I have tried the following things.
The following tries comes up with blank elements in the comboBox
Call the removeAll(), clearValue() functions on the store and re-initialize using the bindStore(model), it comes up with empty list items.
comboBox.store.reload(model);
The following tries adds the new item as a blank element in the comboBox
var data = [];
data.push(new Ext.data.Record({id: options[0].Id, displayField : options[0].Code + ' | ' + options[0].Description}));
comboBox.store.add(data);
comboBox.store.loadData(data, true);
Has anyone seen and struggled with what I am talking about ?
Thanks in advance for your help.
I tried your code and it works with the below change and it is not required to call store.loadData
var data = []; data.push({id: options[0].Id, displayField : options[0].Code + ' | ' + options[0].Description});
comboBox.store.add(data);
What you have done is not the best way to map the returned JSON to your store,
I have modified your code for the mappings which is the best way to do and it doesn't require you to call the load listener and manually add the records.
Ext.define('ReusableComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.reusablecombobox',
queryMode: 'local',
forceSelection: true,
valueField: 'id',
displayField: 'displayField',
autoLoad: false,
initComponent: function () {
if (!this.store) {
var store = Ext.create('Ext.data.Store', {
autoLoad: this.autoLoad,
fields:[ 'Id', 'Code', 'Description', 'IsIncluded', 'IsActive',
{
name: 'displayField',
convert: function(v, record) {
return record.get('Code') + ' | ' + record.get('Description');
}
},
{name: 'id', mapping: 'Id'}
],
proxy: {
type: 'ajax',
url: urlContent('validurl/getcodes'),
reader: {
type: 'json',
root: 'data'
}
}
});
Ext.apply(this, {
store: store
});
}
this.callParent();
}});

How do get jquery fullcalendar to pass additional parameters to my json feed script

My code is as follows
jQuery('#calendar').fullCalendar({
weekMode: 'liquid',
events: themeforce.events,
eventRender: function (event, element) {
element.find('span.fc-event-title').html(element.find('span.fc-event-title').text());
}
});
where themeforce.events is a variable containing an encoded url of the json feed a php file - all works well.
I tried replacing events: themeforce.events, with
events: {
url: themeforce.events,
type: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
However now the calendar fails to load.
What can I do?
I wanted the start and end times for a post ajax request and it took me a bit of time to work it out.
This might help you:
events: function(start, end, timezone, callback) {
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: {
start: start.format(),
end: end.format(),
custom_param1: 'value 1',
custom_param2: 'value 2',
},
error: function () {
alert('there was an error while fetching events!');
},
success: function(doc) {
var events = [];
$.each(doc,function (index, e) {
events.push(e);
});
callback(events);
}
});
}
You should use extraParams as explained in doc : https://fullcalendar.io/docs/events-json-feed
var calendar = new Calendar(calendarEl, {
eventSources: [
// your event source
{
url: '/myfeed.php',
method: 'POST',
extraParams: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
failure: function() {
alert('there was an error while fetching events!');
},
color: 'yellow', // a non-ajax option
textColor: 'black' // a non-ajax option
}
// any other sources...
]
});
Also be sure your feed's url return raw json data array !
Just put "data" instead of "extraParams" in "events"
events: {
url: 'service.php',
method: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
failure: function() {
alert('there was an error while fetching events!');
},
}