Headless-chrome testing breaking when doing test with geolocation or custom handlers - protractor

This is my current protractor config file setup:
const chrome = {
browserName: 'chrome',
unexpectedAlertBehaviour: 'accept',
chromeOptions: {
args: [
'--use-fake-device-for-media-stream',
'--use-fake-ui-for-media-stream',
`--use-file-for-fake-audio-capture=${filesPath}/E2Eaudio.wav`
],
prefs: {
custom_handlers: {
'enabled': true,
'registered_protocol_handlers': [
{
'default': true,
'protocol': 'tel',
'title': '',
'url': `${urls[this.params.cloud]}/?checksw=true&call=%s`
}
]
},
profile: {
managed_default_content_settings: {
notifications: 1,
geolocation: 1
}
},
download: {
// Code Here
}
}
},
loggingPrefs: {
browser: 'ALL'
},
'goog:loggingPrefs': {
browser: 'ALL'
}
};
When doing test invovling tel links or geolocation headless tests break, but when doing the same test non-headless, there are no problems.

Related

What should the publicPath in webpack config be for a dynamic port?

I'm currently building a microfrontend using webpack's module federation, however when I create a deployment in kubernetes it's not resolving because of an incorrect publicPath. It's still a bit complex to me and I'm not sure what to set the publicPath to as the localhost port keeps changing every deployment.
So it looks like: http://127.0.0.1:TUNNEL_PORT, whereby TUNNEL_PORT is dynamic. How would I account for this when defining my output.publicPath?
Webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const deps = require("./package.json").dependencies;
module.exports = {
output: {
publicPath: "http://localhost:3000/",
// publicPath: 'auto',
},
resolve: {
extensions: [".tsx", ".ts", ".jsx", ".js", ".json"],
},
devServer: {
port: 3000,
historyApiFallback: true,
},
module: {
rules: [
{
test: /\.m?js/,
type: "javascript/auto",
resolve: {
fullySpecified: false,
},
},
{
test: /\.(css|s[ac]ss)$/i,
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.(ts|tsx|js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
plugins: [
new ModuleFederationPlugin({
name: "microfrontend1",
filename: "remoteEntry.js",
remotes: {},
exposes: {
"./Header": "./src/Header.tsx",
"./Footer": "./src/Footer.tsx",
},
shared: {
...deps,
react: {
singleton: true,
eager: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
eager: true,
requiredVersion: deps["react-dom"],
},
},
}),
new HtmlWebPackPlugin({
template: "./src/index.html",
}),
],
};

Nestjsx/crud + typeorm + postgres - filter only when certain condition is met

I use those filters on my user controller and they works just fine. But now the system needs to apply some of those filters only when the user is not an super user. how can i use the filter property to check if the user is a su? Here is the actual code:
#Crud({
model: {
type: User,
},
routes: {
createOneBase: {
returnShallow: true
},
updateOneBase: {
returnShallow: true,
},
replaceOneBase: {
returnShallow: true,
},
exclude: ['deleteOneBase', 'updateOneBase', 'createManyBase'],
},
params: {
id: {
field: 'id',
type: 'number',
primary: true,
},
},
query: {
join: {
createdBy: { eager: true, exclude: ['password'] },
updatedBy: { eager: true, exclude: ['password'] },
members: { eager: true, alias: 'groups' },
contacts: {eager: true, alias: 'contacts'},
'members.group': { eager: true },
userCompanies: { eager: true },
'userCompanies.companyId': { eager: true }
},
filter: {
exclude: {
$eq: false,
},
'contacts.exclude': {
$eq: false,
},
'userCompanies.exclude': {
$eq: false,
}
},
sort: [
{
field: 'id',
order: 'ASC',
}
]
}
})
The only one which will be applied no matter the user type is the exclude one.
I've solved by myself using the override method with ParsedRequest.
#Override('getManyBase')
async getMany(#ParsedRequest() req: CrudRequest, #UserReq() user: User) {
if(!user.su) {
req.parsed.filter.push({
field: 'contacts.exclude',
operator: '$eq',
value: false
},
{
field: 'userCompanies.exclude',
operator: '$eq',
value: false
})
}
return await this.service.getMany(req);
}

Google Actions Smart Home on Lambda not working

I've been trying to get my Google Actions Smart Home (nodejs) working in AWS lambda. However it isn't working. Whenever I connect it on the Google Home app, I just get a message of "Couldn't update the setting...". I've already configured the API gateway correctly and set the Handler to "index.smarthome" as shown in the below image link. Why isn't it working, and how can I get my lambda google action smart home working?
Image Link
My firebase version is working though (modified from the washing machine example at https://codelabs.developers.google.com/codelabs/smarthome-washer/#2).
const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');
const app = smarthome();
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: '123',
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
'action.devices.traits.Toggles',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer']
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1'
},
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en'
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en'
}]
}],
ordered: true
}],
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en'
}]
}]
}
}]
}
};
});
app.onExecute((body) => {
const {requestId} = body;
const payload = {
commands: [{
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
}],
};
for (const input of body.inputs) {
for (const command of input.payload.commands) {
for (const device of command.devices) {
const deviceId = device.id;
payload.commands[0].ids.push(deviceId);
for (const execution of command.execution) {
const execCommand = execution.command;
const {params} = execution;
switch (execCommand) {
case 'action.devices.commands.OnOff':
payload.commands[0].states.on = params.on;
break;
case 'action.devices.commands.StartStop':
payload.commands[0].states.isRunning = params.start;
break;
case 'action.devices.commands.PauseUnpause':
payload.commands[0].states.isPaused = params.pause;
break;
case 'action.devices.commands.SetModes':
break;
case 'action.devices.commands.SetToggles':
break;
}
}
}
}
}
return {
requestId: requestId,
payload: payload,
};
});
exports.smarthome = functions.https.onRequest(app);
And here is the code that I used in my AWS lambda function. I referenced https://github.com/actions-on-google/actions-on-google-nodejs & creating dialogflow v2 project with serverless to make it lambda compatible. The main difference between the lambda and firebase versions is the "exports.smarthome" code.
const {smarthome} = require('actions-on-google');
const app = smarthome();
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: '123',
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
'action.devices.traits.Toggles',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer']
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1'
},
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en'
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en'
}]
}],
ordered: true
}],
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en'
}]
}]
}
}]
}
};
});
app.onExecute((body) => {
const {requestId} = body;
const payload = {
commands: [{
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
}],
};
for (const input of body.inputs) {
for (const command of input.payload.commands) {
for (const device of command.devices) {
const deviceId = device.id;
payload.commands[0].ids.push(deviceId);
for (const execution of command.execution) {
const execCommand = execution.command;
const {params} = execution;
switch (execCommand) {
case 'action.devices.commands.OnOff':
payload.commands[0].states.on = params.on;
break;
case 'action.devices.commands.StartStop':
payload.commands[0].states.isRunning = params.start;
break;
case 'action.devices.commands.PauseUnpause':
payload.commands[0].states.isPaused = params.pause;
break;
case 'action.devices.commands.SetModes':
break;
case 'action.devices.commands.SetToggles':
break;
}
}
}
}
}
return {
requestId: requestId,
payload: payload,
};
});
exports.smarthome = function(event, context, callback) {
app.handler(event, {})
.then((res) => {
if (res.status != 200) {
callback(null, {
"fulfillmentText": `I got status code: ${res.status}`
});
} else {
callback(null, res.body);
}
}).catch((e) => {
callback(null, {
"fulfillmentText": `There was an error\n${e}`
});
});
};
Check your AWS CloudWatch logs and see what happens when the lambda is called. You can print to stdout in your lambda and have it show up in these logs.
Along with your Cloudwatch logs, you could also have a look at your Stackdriver logs.

WebDriverError: Could not start Browser / Emulator error

Oflate , I have been observing below error when ran my protractor tests on browserstack.
"UnhandledPromiseRejectionWarning: WebDriverError: Could not start Browser / Emulator"
Here is my protractor config file.
let browserstack = _.defaults({
user: process.env.BROWSERSTACK_USERNAME,
key: process.env.BROWSERSTACK_ACCESS_KEY
}, {
user: '**',
key: '**'
});
let timeoutMultiplier = 2;
exports.makeDefaultCapabilities = function(that) {
return {
browserName: 'chrome',
chromeOptions: {
prefs: {
credentials_enable_service: false,
},
loggingPrefs: {
driver: 'WARNING',
server: 'WARNING',
browser: 'INFO'
},
'browserstack.user': browserstack.user,
'browserstack.key': browserstack.key,
'browserstack.debug': true,
build: that.params.BUILD_NUMBER || '(unknown)',
maxInstances: 2,
name: that.baseUrl,
}
};
exports.config = {
suites: {
e2e: [
'*/*.spec.js'
]
},
SELENIUM_PROMISE_MANAGER: false,
baseUrl: undefined,
framework: 'jasmine',
jasmineNodeOpts: {
defaultTimeoutInterval: 60 * 1000 * timeoutMultiplier,
realtimeFailure: true
},
maxSessions: 1,
params: {
BUILD_NUMBER: undefined,
CI: undefined,
TIMEOUT_MULTIPLIER: timeoutMultiplier
},
seleniumAddress: 'https://hub-cloud.browserstack.com/wd/hub',
useAllAngular2AppRoots: true,
getMultiCapabilities: function() {
return new Promise(function(resolve) {
let capabilities = [];
capabilities.push({
os: 'OS X',
os_version: 'High Sierra'
});
resolve(capabilities);
});
},
onPrepare: function() {
browser.manage().window().maximize();
jasmine.getEnv().addReporter(failFast.init());
let reporter = new SpecReporter();
jasmine.getEnv().addReporter(reporter);
}
};
Test that is failing :
calling function :
async clickButton() {
await browser.waitForAngularEnabled(false);
await waitForEl(this.Button);
await browser.sleep(10000);
await this.Button.click();
await browser.sleep(10000);
await this.stopButton.click();
await waitForElAbsence(this.Bar);
await browser.waitForAngularEnabled(true);
}
used above calling function in below spec:
it('should check if button is clicable', async function() {
let po = new check({
url
});
await po.go();
await po.clickButton();
});
Has any one experienced it before ? Also the error is seen only browserstack and not on my local computer. Also the test i pasted is not the only one failing . Tests are failing randomly with this error.
I have protractor v5.3.2

Gerkin and Cucumber in Angular 5: Undefined

When I try to create a test using Cucumber and Gherkin I get a strange error. I show you the error first, then the files login.step.ts and login.po.ts:
// Error:
Undefined. Implement with the following snippet:
When('Enter the card number in the box', function () {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
// login.step.ts
import { expect } from 'chai';
const { Given, When, Then, Before } = require('cucumber');
import { browser, by, element } from 'protractor';
import { LoginPage } from './login.po';
let login: LoginPage;
Before(() => {
login = new LoginPage();
});
Given(/^Entering in Login$/, { timeout: 10 * 5000 }, async () => {
await browser.get('http://localhost:49152/login');
});
When(/^Enter the card number in the box$/, () => {
// login.setCardNumber('1234').then((txt) => {
// return 'ready!?';
// })
login.setCardNumber('1234');
});
// login.po.ts
import { browser, by, element, until } from 'protractor';
export class LoginPage {
navigateTo() {
return browser.get('/login');
}
setCardNumber(cardNumber) {
const input = element(by.css('#box'));
return input.sendKeys(cardNumber);
}
}
The first test passes successfully, but in the second test, the process ends in error.
[EDIT]
Adding the protractor.conf.js file:
exports.config = {
allScriptsTimeout: 11000,
specs: [
// './e2e/**/*.e2e-spec.ts',
'./e2e/features/*.feature'
],
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: ['disable-infobars']
},
metadata: {
browser: {
name: 'chrome',
version: '58'
},
device: 'Xubuntu Linux',
platform: {
name: 'Linux',
version: '16.04'
}
}
},
directConnect: true,
frameworkPath: require.resolve('protractor-cucumber-framework'),
plugins: [{
package: 'protractor-multiple-cucumber-html-reporter-plugin',
options: {
automaticallyGenerateReport: true,
removeExistingJsonReportFile: true
}
}],
cucumberOpts: {
require: ['./e2e/steps/**/*.ts', './e2e/support/*.ts'],
tags: [],
dryRun: false,
compiler: [],
format: 'json:reports/results.json',
strict: true
},
baseUrl: 'http://localhost:4200/',
SELENIUM_PROMISE_MANAGER: false,
framework: 'custom',
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
}
};
remove the double quote " behind box in /^Enter the card number in the box"$/
I found the answer to my problem. I only had to include the following configuration line to my Before() step in my test:
browser.ignoreSynchronization = true;
According to what I read in different places, it seems that Chrome is looking to perform some task with sockets, and with this line we are disabling this task.