Export reusable Javascript function in Cypress test spec file - javascript

I am trying to have a reusable component in my Cypress spec file, which is organized by our system 'services'. There are code pieces that I would like to make available as component for other JS files.
However, I found the 'import' statement results in running of B.js's test cases, and I cannot find a way to avoid 'Testcase B' from running.
I know there is custom commands in Cypress, but in my case, I would like to use pure JS to organize my component. Thank you.
A.js
import {functionInB as helloB } from "./B"
describe(`A`, () => {
it(`01 Testcase A`, () => {
let result = helloB()
console.log(result)
})
});
B.js
describe(`B`, () => {
it(`01 Testcase B`, () => {
//let result = Hello2()
console.log("inside hello B")
})
});
export function functionInB(){
return "Do something in functionInB"
}

There doesn't seem to be a way to stop a script running on import (or require() or dynamic import()).
In Python __main__ (docs) is used to determine if a module is called at the "top level".
if __name__ == "__main__":
# execute only if run as a script
main()
It's a bit hacky, but you can use Cypress.spec.name to do the same thing and only run B's code when it is the current spec.
if (Cypress.spec.name === 'B.js') {
describe(`B`, () => {
it(`01 Testcase B`, () => {
//let result = Hello2()
console.log("inside hello B")
})
});
}
export function functionInB(){
return "Do something in functionInB"
}
The "javascript way" would be to move functionInB() to a utility file and import in it both tests, but I guess you already know that.

Related

Javascript intellisense and ctrl+click not working while using fixtures

I am performing playwright test automation using fixtures and have files as below. While running its working as expected so i know its not a playwright issue. My question is when i ctrl+click on loadAndLogin under test.step in TC_123.js with VS code, i am expecting it to navigate to the loadAndLogin method in LoadAndLogin.js. But this is not happening and how do i fix this?
// basePage.js
const base = require('#playwright/test');
const { LoadAndLogin } = require('../utilities/LoadAndLogin');
exports.test = base.test.extend({
loadAndLogin: async ({ page }, use) => {
await use(new LoadAndLogin(page));
},
});
exports.expect = base.expect;
// LoadAndLogin.js
const { test, expect } = require('#playwright/test');
const { LoginPage } = require('../pages/LoginPage');
exports.LoadAndLogin = class LoadAndLogin {
constructor(page) {
this.page = page;
this.loginPage = new LoginPage(page);
}
async loadAndLogin() {
// code to Login to the application
}
}
// TC_123.js
const { test } = require('../../fixtures/basePage');
test('TC_123', async function ({page, loadAndLogin}) {
await test.step('01_Load application and login', async function () {
await loadAndLogin.loadAndLogin();
});
});
I tried checking with playwright team in github and below was the response
https://github.com/microsoft/playwright/issues/20218
You need to either add // #ts-check and javascript type annotations and use type script to make the navigation work for fixtures. VSCode fails to infer all the types looking at the javascript code alone. Closing this issue as it is not a playwright defect. Also feel free to open a request for VS Code team.
i tried using //#ts-check and even created jsconfig.json but still i am not able to understand why it is not working

Mocha Does Not Run Second describe()

I am writing a test coverage for my code base and just started using Mocha/Chai for my backend. For whatever reason I can't get my second describe() to run in this function. I don't receive any error, it just exits after running the first describe() suite.
export async function testCreateUnknownCustomer(billCodeTest) {
let unknownRecordTest;
describe("Create A Unknown Customer Record", function () {
it("Creates a new unknown customer", async function () {
unknownRecordTest = await CustomersController.createUnknownCustomer(
'+15555551111',
billCodeTest
)
})
it('Should Be a Instance of a Sequelize Model', function () {
expect(unknownRecordTest instanceof Model).equals(true);
})
});
describe("Hard Delete unknown customer record", function () {
const unknownID = unknownRecordTest.customer_id;
it("Deletes a customer record", async function () {
console.log(await unknownRecordTest.destroy());
console.log(unknownRecordTest);
})
});
}
Leaving the describes raw in the file seems to have fixed everything. As opposed to wrapping it in a function that is exported and run in a main.test.js execution file. I don't really have a technical explanation why secondary describes wouldn't have executed regardless.

Ember.JS concurrency task, perform() is not a function

I was trying to convert a function over to a task. Here is the original code:
Call:
this.socketConnect(endpoint, token);
Function:
socketConnect = async (token, endpoint) => {
this.socket = new WebSocket(endpoint + '?auth=' + token);
this.socket.addEventListener('open', () => {
this.socket.addEventListener('message', event => this.handleMessage(event));
this.socket.addEventListener('close', event => this.retryConnection(event, endpoint));
});
}
I've been following structure on implementing Ember tasks. It all compiles with no issue, however when it gets called, it outputs that this.socketConnect(...) is not a function. Before hand I didn't have the return below and it output that this.socketConnect wasn't a function. Here is my current code for a task.
Import:
import { task } from 'ember-concurrency';
Call:
this.socketConnect(endpoint, authToken).perform();
Function:
#task *socketConnect(endpoint, token) {
yield async () => {
this.socket = new WebSocket(endpoint + '?auth=' + token);
this.socket.addEventListener('open', () => {
this.socket.addEventListener('message', event => this.handleMessage(event));
this.socket.addEventListener('close', event => this.retryConnection(event, endpoint));
});
return;
};
}
New to this, so I'm guessing there's something small I'm missing. It matches other uses. Also if anyone could help on the benefits of switching a websocket generation function to a task? Any help would be appreciated, thank you.
The #task decorator isn't part of the official ember-concurency package yet. The official version lives in ember-concurrency-decorators for now. You'll need to
ember install ember-concurrency-decorators
and then you can do
import { task } from 'ember-concurrency-decorators';
To use it.
Alternatively you can use a different syntax if you don't want another dependency.
import { task } from 'ember-concurrency';
class Foo {
#(task(function*() {
// ...
}).restartable())
doStuff;
executeTheTask() {
this.doStuff.perform();
}
}
To call the task the syntax is:
this.socketConnect.perform(endpoint, authToken);
As you're not calling socketConnect directly, you want to call the method that ember concurrency generates for you.

Jest: Testing API Methods from Intercom

I am having trouble understanding what the testing flow would be for testing functions which use functions loaded from a JavaScript library from Intercom.
My method looks like this:
export const generateButton = (handleOnClick) => {
case "moo":
return <button onClick={() => Intercom('show')}>Sign Up</button>
default:
return 'moo'
The error I get when running this is:
ReferenceError: Intercom is not defined
So I figured it out, I needed to add a new file and point jest set up on package.json to it like so (the file added is mockObject)
"setupFiles": [
"./config/jest/setupJest.js",
"./config/jest/mockObject.js"
],
then in the file itself has this in it
global.Intercom = () => {
console.log('Intercom called')
}
If I understand what you're trying to do then create a dummyFunction to replace Intercom in your tests. Something like this...
const Intercom = jest.fn();
describe('button click', () => {
it('Intercom is called correctly', () => {
// whatever component contains the button should be mounted
const wrapper = mount(<YourComponentHere />);
// you may need to add a class to target the specific button
wrapper.find('button').simulate('click');
expect(dummyFunction).toHaveBeenCalledWith('show');
expect(dummyFunction).toHaveBeenCalledTimes(1);
});
});

Webpack 4: How to call a global function with arguments?

I'm writing a new build script for my project using Webpack 4, so far, I have not faced any issue until today, when I have to call a global function with parameters.
Below is an example, I did without parameters for Google reCaptcha:
const enableFormButton = () => {
var elements = "#form_submit_btn, #form_submit_btn_alt";
$(elements).removeAttr("disabled");
$(elements).css({"cursor":"pointer"});
$(elements).removeClass("button button-3d button-red button-small").addClass("button button-3d button-green-invert button-small");
}
const recaptcha = document.querySelectorAll(".g-recaptcha");
recaptcha.forEach((captcha) => {
captcha.setAttribute('data-callback', 'enableFormButton');
});
export { enableFormButton }
and in my entry index.js file, it would look like this:
import {enableFormButton} from './some_js_file'
window.enableFormButton = enableFormButton
Now, this is what I tried with a global function with parameters:
const exampleFunction = (arg1) => {
// do something here
}
export {exampleFunction}
and in the index.js file:
import {exampleFunction} from './some_js_file'
window.exampleFunction = exampleFunction
I tried it, there are no build errors but I get an error in the console saying
"Uncaught TypeError: exampleFunction is not a function"
Any idea on how to solve this? Btw, I'm kind of new to using Webpack.
Thanks to #CertainPerformance's tip, I added the export keyword to the function exampleFunction(arg1), which should look like this:
export exampleFunction(arg1){
// something
}
Imported the function to another .js file:
import {exampleFunction} from './somescript';
And then, it worked! :)
So turns out, I learnt something for the day!

Categories

Resources