Cypress: cy.window(): Unable to get property values - cypress

Goal
Hello, I wish to gather custom property values for a window object of a page using cy.window().
Issue
When using cy.log() jointly with JSON.stringify(), it presents that it does have properties with values; however, when using lodash _.has(), does not have these properties and thereby no value because these properties are not found.
Code
The following Cypress custom command using cy.window() gathers custom window's property
export function cmdCypressWindow($propName: string) {
cy.window()
.its($propName)
.then(($propValue: Cypress.AUTWindow) => {
cy.log('props names:', JSON.stringify(Object.getOwnPropertyNames($propValue), null, 2));
cy.log('props values:', JSON.stringify($propValue, null, 2));
cy.log('VERSION prop:', _.has($propValue, 'VERSION'));
cy.log('HOST prop:', _.has($propValue, 'HOST'));
cy.log('VERSION value:', _.get($propValue, 'VERSION'));
cy.log('HOST value:', _.get($propValue, 'HOST'));
});
}
Passed in for parameter $propName value 'ACT', because I am expecting the page's window object to contain window.ACT["VERSION"].
Using the example code, the log output shows that the page's window does contain property ACT["VERSION"].
However, when accessing this window object, listed properties are unavailable and undefined:
window
- its .ACT
log props names:, [ "__esModule", "VERSION", "HOST", "RulesList", "RulesAddEdit", "AppsList", "AppsOAuth", "AppsAdd" ]
log props values:, { "VERSION": "0.2.11", "HOST": "radmin" }
log VERSION prop:, false
log HOST prop:, false
log VERSION value:
log HOST value:
How do I resolve this? Thank you, all feedback is very much appreciated.

Found part of the solution here:
TypeScript: Find Key / Value in Object (list comprehension?)
Modified the function:
export function cmdCypressWindow($propName: string) {
cy.window()
.its($propName)
.then(($propValue: Cypress.AUTWindow) => {
const actValues: Record<string, string> = {};
Object.keys($propValue).forEach(key => {
// #ts-ignore
if (typeof $propValue[key] !== 'function') {
// #ts-ignore
actValues[key as string] = $propValue[key];
}
});
cy.log(`window.${$propName}`, JSON.stringify(actValues, null, 2));
cy.wrap(actValues);
});
}
Results show that I was able to acquire values from window object:
log props names:, [ "__esModule", "VERSION", "HOST", "RulesList", "RulesAddEdit", "AppsList", "AppsOAuth", "AppsAdd" ]
log window.ACT, { "VERSION": "0.2.11", "HOST": "radmin" }
wrap {version: 0.2.11, host: radmin}

Related

Azure Application Insights - recreate the singleton instance with the modified configuration

I would like to track Sql command texts using Application Insights (Setting/ overriding the value of EnableSqlCommandTextInstrumentation in a running application) on a demand basis through a reloadable configuration. The ConfigureTelemetryModule of Microsoft.ApplicationInsights SDK uses singleton registration and this limits me from using IOptionsSnapshot. Can anyone please suggest me some ideas to override the config value EnableSqlCommandTextInstrumentation at runtime? Thank you.
Program.cs
var builder = WebApplication.CreateBuilder(args);
...
var myOptions = new MyOptions();
var configSection = builder.Configuration.GetSection(MyOptions.Name);
configSection.Bind(myOptions);
builder.Services.Configure<MyOptions>(configSection);
builder.Services
.AddSingleton<ITelemetryInitializer>(_ => new MyTelemetryInitializer(applicationName))
.ConfigureTelemetryModule<DependencyTrackingTelemetryModule>(
(module, _) =>
{
module.EnableSqlCommandTextInstrumentation = myOptions.EnableSqlCommandTextInstrumentation;
})
.AddApplicationInsightsTelemetry(configuration);
Can anyone please suggest me some ideas to override the config value EnableSqlCommandTextInstrumentation at runtime?
AFAIK, we cannot add configuration value run time to EnableSqlCommandTextInstrumentation.
The module.EnableSqlCommandTextInstrumentation has accept the bool value either we can enable or disable the EnableSqlCommandTextInstrumentation.
As per the MS-Doc you have to keep the settings in your host.json file "EnableDependencyTracking": true
Program.cs
builder.Services
.AddSingleton<ITelemetryInitializer>(_ => new MyTelemetryInitializer(applicationName))
.ConfigureTelemetryModule<DependencyTrackingTelemetryModule>(
(module, _) =>
{
module.EnableSqlCommandTextInstrumentation = true;
})
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": false,
"excludedTypes": "Exception"
},
"dependencyTrackingOptions": {
// Enable the Sql command text instrumentation to true to collect data
"enableSqlCommandTextInstrumentation": true
}
},

Cypress: Is cypress-plugin-snapshots supported in Cypress 10?

I am getting this error when I am trying to run any of my specs file. It was working before. Am I missing a step here? How do I mark the path as external?
I removed parts of images that contain sensitive information.
e2e.js
require('cypress-plugin-tab')
import './commands'
const dayjs = require('dayjs')
Cypress.dayjs = dayjs
import 'cypress-plugin-snapshots/commands';
(Edited)
I tried to reinstall the package again but I am now currently getting this error. When I tried to npm install --force crypto I am back with this error plus I have to do npm install path also. It's like an endless loop.
Edited againThis is the view from the terminal. How do I use "platform: 'node'" ??
(Edited again)
I took the default Cypress project, installed and ran cypress-plugin-snapshots but sadly it worked ok.
Here are the files
cypress.config.js
const { defineConfig } = require("cypress");
const { initPlugin } = require('cypress-plugin-snapshots/plugin');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
initPlugin(on, config); // this is cypress/plugins/index.js in Cypress v9
return config;
},
excludeSpecPattern: [ // this is "ignoreTestFiles" in Cypress v9
"**/__snapshots__/*",
"**/__image_snapshots__/*"
],
"env": { // just pasted everything from the docs here
"cypress-plugin-snapshots": {
"autoCleanUp": false, // Automatically remove snapshots that are not used by test
"autopassNewSnapshots": true, // Automatically save & pass new/non-existing snapshots
"diffLines": 3, // How many lines to include in the diff modal
"excludeFields": [], // Array of fieldnames that should be excluded from snapshot
"ignoreExtraArrayItems": false, // Ignore if there are extra array items in result
"ignoreExtraFields": false, // Ignore extra fields that are not in `snapshot`
"normalizeJson": true, // Alphabetically sort keys in JSON
"prettier": true, // Enable `prettier` for formatting HTML before comparison
"imageConfig": {
"createDiffImage": true, // Should a "diff image" be created, can be disabled for performance
"resizeDevicePixelRatio": true,// Resize image to base resolution when Cypress is running on high DPI screen, `cypress run` always runs on base resolution
"threshold": 0.01, // Amount in pixels or percentage before snapshot image is invalid
"thresholdType": "percent" // Can be either "pixels" or "percent"
},
"screenshotConfig": { // See https://docs.cypress.io/api/commands/screenshot.html#Arguments
"blackout": [],
"capture": "fullPage",
"clip": null,
"disableTimersAndAnimations": true,
"log": false,
"scale": false,
"timeout": 30000
},
"serverEnabled": true, // Enable "update snapshot" server and button in diff modal
"serverHost": "localhost", // Hostname for "update snapshot server"
"serverPort": 2121, // Port number for "update snapshot server"
"updateSnapshots": false, // Automatically update snapshots, useful if you have lots of changes
"backgroundBlend": "difference" // background-blend-mode for diff image, useful to switch to "overlay"
}
}
},
});
cypress/support/e2e/js
import './commands'
import 'cypress-plugin-snapshots/commands';
Test
describe('empty spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
.then(() => {
cy.get('div').toMatchSnapshot(); // 1st run - logs "update snapshot"
// 2nd run - logs "snapshots match"
});
})
})

Says Jasmine spy is not being called, but I can see that its being called

I can't figure out why Jasmine is claiming that the function I'm spying on isn't being called, especially since it is logging in buildLinksObj when called through and not calling when I remove .and.callThrough() I feel like I've written similar code a bunch of times before without any problem. I'm using Jasmine 2.9
The error message I'm getting is:
1) addToLinks should call buildLinksObj if its given an object with children
it should add the personalized links to PageApp.meta.analytics.links
Expected spy buildLinksObj to have been called.
at UserContext.<anonymous> (http://localhost:9877webpack:///tests/specs/common/FetchPersonalContent.spec.js:854:0 <- tests/app-mcom.js:104553:48)
Here's the except of my code:
FetchPersonalContent.js
const buildLinksObj = (responseObj = {}, targetObj, PageApp) => {
console.log('it logs in buildLinksObj') // This is logging!
}
const addToLinks = (responseArr, personalizedLinks) => {
responseArr.forEach((media) => {
const type = media.type;
const typeObj = media[type];
buildLinksObj(typeObj, personalizedLinks, PageApp);
if (typeObj && typeObj.children) {
console.log('has children!')
console.log('typeObj.children is: ', typeObj.children);
typeObj.children.forEach((child) => {
console.log('has a child')
buildLinksObj(child, personalizedLinks, PageApp);
console.log('buildLinksObj was definitely called. what the heck?')
});
}
});
}
export {buildLinksObj, addToLinks, FetchPersonalContent as default,
};
FetchPersonalContent.spec.js
import * as FetchPersonalContent from '../../../src/FetchPersonalContent'; // my path is definitely correct
describe('it should add the personalized links to PageApp.meta.analytics.links', () => {
it('addToLinks should call buildLinksObj if its given an object with children ', () => {
spyOn(FetchPersonalContent, 'buildLinksObj').and.callThrough();
FetchPersonalContent.addToLinks([{
"personalId": 30718,
"type": "carousel",
"carousel": {}
}], {});
expect(FetchPersonalContent.buildLinksObj).toHaveBeenCalled();
});
});
I'd really appreciate any help!
I have a feeling FetchPersonalContent.buildLinksObj in the spec file is not pointing to the same instance as buildLinksObj in the FetchPersonalContent.js file.
Why is export {FetchPersonalContent as default} required? I am assuming you have shared the complete content of FetchPersonalContent.js in your question.
Possible solutions:
You can try removing FetchPersonalContent from the export statement.
Or
Instead of
export {buildLinksObj, addToLinks, FetchPersonalContent as default,
};
You can directly export the constants in FetchPersonalContent.js file.

Detailed Reporting Cypress/Mochawesome

Has anyone had much experience of generating good detailed reports from Cypress tests using Mochawesome as the report engine?
I've followed the info on the Mochawesome GIT page but what I get is rather dull!!
I'd like to be able to include the odd screen-shot and the output from the assertions - here's the current cypress.json file......
{
"projectId": "haw8v6",
"baseUrl": "https://obmng.dbm.guestline.net/",
"chromeWebSecurity": false,
"reporter" : "mochawesome",
"reporterOptions" : {
"reportFilename" : "DBM Smoke-Test",
"overwrite": true,
"inline": true
}
}
I've been toying with var addContext = require('mochawesome/addContext'); but with little joy.
Suggestions gratefully received.
Thanks
As per request below - very basic example of addContext
var addContext = require('mochawesome/addContext');
describe('DBM Smoketests', function() {
it('E2E Hotel2 WorldPay System', function() {
cy.visit('https://obmng.dbm.guestline.net/');
cy.url().should('include','/obmng.dbm');
addContext(this,'URL is correct');
//loads hotel 2
cy.get('.jss189 > div > .jss69 > .jss230').click();
After much hacking about, I found a way to use Mochawesome addContext in Cypress.
Note, you can only make one addContext call per test (this is a Mochawesome limitation).
describe('DBM Smoketests', function() {
it('E2E Hotel2 WorldPay System', function() {
cy.visit('https://obmng.dbm.guestline.net/');
cy.url().should('include','/obmng.dbm');
Cypress.on('test:after:run', (test) => {
addContext({ test }, {
title: 'This is my context title',
value: 'This is my context value'
})
});
});
});
The second param is the context to be attached to the test, and it must have non-empty title and a value properties.
What you get in the mochawesome.json output is
...
"suites": [
{
...
"tests": [
{
"title": "E2E Hotel2 WorldPay System",
...
"context": "{\n \"title\": \"This is my context title\",\n \"value\": \"This is my context value\"\n}",
"code": "...",
...
}
],
In mochawesome.html, on clicking the test you get
Additional Test Context
This is my context title:
This is my context value
I have not tried it out with value types other than string.
Note for anyone starting out with Mochawesome in Cypress, it looks like you can only get a Mochawesome report with running cypress run, not with cypress open - although there may be a way around this using mocha's multiple reporter functionality.
Yes confirmed work! It's possible to call once in each test like this:
it('Should shine the test report!!!', () => {
cy.get('li').should('have.length.greaterThan', 0);
addTestContext('String','giphy');
addTestContext('Link','https://giphy.com');
addTestContext('Image','https://media.giphy.com/media/tIIdsiWAaBNYY/giphy.gif');
addTestContext('Image','https://media.giphy.com/media/tIIdsiWAaBNYY/giphy.gif');
});
function addTestContext(title, value) {
cy.once('test:after:run', test => addContext({ test }, { title, value }));
}

How to get deviceName value from Multicapabilities definition in protractor config

This might be repeated question for you guys but really I didn't get answer yet.
Here is my multi-capabilities definition in protractor config file.
I want to access the deviceName parameter value. How can I do it?
exports.config = {
directConnect:true,
multiCapabilities: [
{
browserName: 'chrome',
'chromeOptions': {
'mobileEmulation': {
'deviceName': 'iPad'
}
}
}
],
Tried under onPrepare but not giving multi-capabilities values
browser.getCapabilities().then(function(c) {
console.log(c.get('deviceName'));
});
Not sure about solving with getCapabilities(), but you should be able to solve this with getProcessedConfig().
getProcessedConfig will return a promise of your entire configuration settings (and a few protractor defaults). So taking your example:
browser.getProcessedConfig().then((c) => {
console.log(c.capabilities.chromeOptions.mobileEmulation.deviceName);
});
You could make console.log(process.env) in the onPrepare block and find what you want.
Try getProcessedConfig()
http://www.protractortest.org/#/api?view=ProtractorBrowser.prototype.getProcessedConfig
Or just plain old stupid:
let device_name = 'iPad'
exports.config = {
directConnect: true,
multiCapabilities: [{
browserName: 'chrome',
chromeOptions: {
mobileEmulation: {
deviceName: device_name
}
}
}],
onPrepare: function () {
console.log('Device name will be', device_name);
}
Fetching device name worked as advised by Gunderson but now I am running into different issue I am unable to access the variable value outside the code block while in onPrepare.
onPrepare: function () {
browser.getProcessedConfig().then(function (c) {
return global.deviceName
c.capabilities.chromeOptions.mobileEmulation.deviceName;
}).then(function () {
console.log("Device Name is:" + global.deviceName);
customDevice = global.deviceName;
}
);
};
customDevice not printing any value.....which is define as global variable on top of the configuration file.
I know might be doing silly mistake in accessing it...:)

Resources