Proteactor- jasmine - How to execute one js file inside another js - jasmine

Suppose have A.js file with 10 it blocks, now in middle of exuction say in 6th it block need to execute another more js file say B.js

I'm not sure this is what you mean, but you could have several describe blocks with their it blocks inside of them.
describe('Main file', () => {
describe('Describe A', () => {
it('some it block from A', async () => {
// code here
});
});
describe('Describe B', () => {
it('some it block from B', async () => {
// code here
});
});
});

Related

Cypress test: Writing multiple elements to database failed

Trying to write multiple elements into database failed, only the last one is written:
// my_test.cy.js
import CreateProductPage from "../pages/CreateProductPage";
describe('product detail page', () => {
beforeEach(() => {
cy.login('admin', 'shop')
})
it('should print typed product', () => {
cy.createProduct(null, 'Component Product 0', '0')
CreateProductPage.elements.productDetailTabs().should('exist') // <--- to detect that the entity is written
cy.createProduct('combinable', 'Combined Test Product', '0')
CreateProductPage.elements.productDetailTabs().should('exist') // <--- to detect that the entity is written
})
})
// commands.js
Cypress.Commands.add('createProduct', (type, name, grossPrice) => {
cy.visit('/#/sw/product/create')
CreateProductPage.elements.productDetailTabs().should('not.exist').then(() => {
if(type === 'combinable') {
CreateProductPage.elements.radioBtnCombinableProduct().click()
}
CreateProductPage.elements.inputProductName().clear().type(name)
CreateProductPage.elements.inputPriceFieldGross().type(grossPrice)
SwPageHeader.elements.btnProductSave().click()
})
})
Questions:
This failed because of asynchronous nature of cypress?
If so, how to interrupt? Chaining with then(), the behavior is the same
With this is code (adding wait()) it works, but i'm looking for the right way
// my_test.cy.js
describe('product detail page', () => {
beforeEach(() => {
cy.login('admin', 'shop')
})
it('should print typed product', () => {
cy.createProduct(null, 'Component Product 0', '0')
CreateProductPage.elements.productDetailTabs().should('exist')
cy.wait(300)
cy.createProduct('combinable', 'Combined Test Product', '0')
CreateProductPage.elements.productDetailTabs().should('exist')
})
})
EDIT 1
// pages/CreateProductPage.js
class CreateProductPage {
elements = {
productDetailTabs: () => cy.get('div.sw-product-detail-page__tabs'),
radioBtnCombinableProduct: () => cy.get('.sw-product-detail-base__info input#type_combinable_product-0'),
radioBtnUnCombinableProduct: () => cy.get('.sw-product-detail-base__info input#type_combinable_product-1'),
inputProductName: () => cy.get('input#sw-field--product-name'),
inputPriceFieldGross: () => cy.get('div.sw-list-price-field__price input#sw-price-field-gross'),
}
}
module.exports = new CreateProductPage();
If the problem is one of waiting, you will need to figure out something that indicates to the user that the save was successful and test that.
For example, if there was a toast message on screen:
...
SwPageHeader.elements.btnProductSave().click()
cy.contains('span', 'Product was saved').should('be.visible')
Blockquote
This failed because of asynchronous nature of cypress?
Code behaves synchronously if you have only cy commands inside the code block.
As suggested in https://stackoverflow.com/a/74721728/9088832 you should wait for some element to appear or for an API request to be completed that is responsible for the product creation.

Cypress: Code in page object file is being executed as a test case before the before hook

I was trying to use a condition as a function within a page object.
class Folders {
DropdownCheckFunction(){
cy.get('.more-less-container').then((dropdown) => {
if(dropdown.find('.name').contains('More')){
cy.get('more-less-container').click()
}
else{
console.log('folders are in expanded state')
}
})
}
Drafts(){
this.DropdownCheckFunction()
cy.get('.category-content').find('[title="Drafts"]').click()
.get(".folder-details").should('contain.text', 'Drafts')
}
Issue here is that the page object is getting executed as a test case and is happening before the code in BEFORE hook is being run. Below is the test file code
describe('Testing all cases related to Drafts', () => {
before(() => {
cy.login()
})
})
it('Needs to open the Drafts folder', () => {
openFolder.Drafts()
});
Attaching the error seen on the test runner for reference
The problem is bad formatting.
If you line up your code, you can see it - your test is outside the scope of the before().
describe('Testing all cases related to Drafts', () => {
before(() => {
cy.login()
})
}) // move this bracket to below the `it()`
it ('Needs to open the Drafts folder', () => {
openFolder.Drafts()
});

Angular jasmine how to spy an async spy method

I am new to writing test with async/await in angular.
I have the following code. The service method is an async method. The test fails saying component.options.length is 0.
Can anyone please help me how to fix the error so the options has got the value i set in spy?
Thanks
spec.ts
spySideNavService = jasmine.createSpyObj('SideNavService', [], {
setOrgUserDetails: () => {},
loadMenus: () =>
[
{
id: 'my-menu',
label: 'My Menu',
icon: 'far fa-envelope fa-2x',
url: 'url'
}
] as NavOption[]
});
describe('ngOnInit', () => {
it('should add navigation options', () => {
expect(component.options.length).toBeGreaterThan(0);
});
});
component:
ngOnInit(): void {
this.options = await this.sideNavService.loadMenus();
}
SideNavService:
async loadMenus(): Promise<NavOption[]> {
//logic
}
Tried answer given below but still not working:
describe('ngOnInit', () => {
it('should add navigation options', fakeAsync(() => {
// !! call tick(); to tell the test to resolve all promises
// before coming to my expect line
tick();
expect(component.options.length).toBeGreaterThan(0);
}));
});
You need to use fakeAsync/tick to control promises.
// !! add fakeAsync
it('should add navigation options', fakeAsync(() => {
// !! call tick(); to tell the test to resolve all promises
// before coming to my expect line
// !! call ngOnInit
component.ngOnInit();
console.log(component.options);
tick();
console.log(component.options);
expect(component.options.length).toBeGreaterThan(0);
}));
Before, the test would go to the await line and go back to the test for the expect because the await is saying to do this later. Now with the tick, we are saying if they are any promises created, resolve them before moving forward.
Also, I think you're missing a Promise.resolve on loadMenus.
loadMenus: () => Promise.resolve(
[
{
id: 'my-menu',
label: 'My Menu',
icon: 'far fa-envelope fa-2x',
url: 'url'
}
] as NavOption[])
I am thinking the Promise.resolve is required so it can be awaited.
edit
I don't think the done callback will help you.
You can try using await fixture.whenStable() to wait for the promise(s). Try this:
describe('ngOnInit', () => {
it('should add navigation options', async () => {
component.ngOnInit();
await fixture.whenStable();
expect(component.options.length).toBeGreaterThan(0);
});
});

Run function after beforeEach

I need to run a function before my tests, but after all beforeEaches. Is there a way of prioritise beforeEaches, reorder them or monkeypatching something so that I can run a function before test gets executed?
Reason: I want to count how many database calls my tests do, but not include those that beforeEach calls.
Mocha executes the beforeEach hooks that pertain to a test in the order in which it encountered them in your code, so there should not be a need to monkeypatch. For instance:
describe("top", () => {
beforeEach(() => {
console.log("A");
});
describe("down", () => {
beforeEach(() => {
console.log("B");
});
beforeEach(() => {
console.log("C");
// Put your code here.
});
it("test 1", () => {});
it("test 2", () => {});
});
});
The above outputs:
top
down
A
B
C
✓ test 1
A
B
C
✓ test 2

Conditionally run tests at runtime using Nightwatchjs

I'm using nightwatch to run my end to end tests but I would like to conditionally run certain tests based on some global settings at runtime.
// globals.js
module.exports = {
FLAG: true
};
// test.js
describe('Something', () => {
it('should do something', client => {
if (client.globals.FLAG) {
expect(1).to.equal(1);
}
});
});
The above works fine, but I want to silent the whole test and conditionally include the it e.g:
// test.js
describe('Something', () => {
// client does not exist out here so it does not work.
if (client.globals.FLAG) {
it('should do something', client => {
expect(1).to.equal(1);
});
}
});
I am aware I can skip tests by defining them in the nightwatch.js and excluding files etc etc but thats not the approach I can use in this implementation. Another solution might be to use tags but I'm not sure this is possible using Mocha.
You could access the flag in the second example by importing your module globals.js:
// test.js
const globals = require('../globals.js');
describe('Something', () => {
if (globals.FLAG) {
it('should do something', client => {
expect(1).to.equal(1);
});
}
});
you could also create a function to ignore the test when the condition is met:
// test.js
const FLAG = require('../globals.js').FLAG;
const not = function(v){ return {it: v ? function(){}: it} };
describe('Something', () => {
not(FLAG).it('should do something', client => {
expect(1).to.equal(1);
});
});

Resources