cypress - how to compare href to anchor text - cypress

I'm wondering how to test using cypress libary if the href attribute include the text from anchor tag. The code is as follow:
I have a div with a lot of anchors with data attribute.
<div>
#hash1
#hash2
#hash3
// and many more
</div>
I stared testing with check if each element have "#", href attribute with "/tag/" :
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
cy.wrap(item).contains('#').should('have.attr', 'href').and('contain', '/tag/');
})
})
});
but how can I check if href include the displayed text from a tag?

Once you've yielded the element from your cy.get(), you can reference it as a jQuery object. In this case, we'll want to get the text.
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
cy.wrap(item).contains('#').should('have.attr', 'href', `/tag/${item.text().replace('#', '')}`)
})
})
});
If you simply wanted to see if the href contains the text, you could use the jQuery attr function.
describe('Test', () => {
it('should navigate to link from hashtag', () => {
cy.visit('/');
cy.get('[data-cy="hashtag"]').each((item) => {
expect(item.text()).to.contain('#');
expect(item.attr('href')).to.contain(item.text().replace('#', ''));
})
})
});

Related

Why defaultTimeOut is not working when checking images if visible?

I need help on implementing the defaultTimeOut and I have this code:
it('Check Image if visible', () => {
//IMG
cy.get('[class^="image1"]:nth-child(1) img').should('have.length', 5)
.each(($el) => {
expect($el).to.be.visible
})
});
it('Check Image 2 if visible', () => {
//IMG
cy.get('[class^="image2"]:nth-child(1) img').should('have.length', 5)
.each(($el) => {
expect($el).to.be.visible
})
});
But it checks the images in an instant it doesn't wait 4000ms for the image to load and check if it's visible even if i set the {timeout:10000} in the element and defaultTimeOut:10000 on config. as far as i want i don't want to use cy.wait. Do you have any recommendations?
I think the reason is the <img> element is there but the image content has not loaded.
Try
cy.wrap($el)
.should('be.visible')
.and('have.prop', 'naturalWidth')
.should('be.greaterThan', 0)

cypress each method get a child elements href

I'm using an each method in cypress to find a list of li elements.
What I'm after is to find a child inside the li and test its href value.
The child is an a tag.
Here is what I have so far:
it("should have ..... ", () => {
cy.get("ul > li")
.each((el, index, list) => {
expect(el.text()).to.be.oneOf(["hello", "world"]);
const a = cy.wrap(el).find("a");
expect(a.attr("href")).to.be.oneOf(["/hello", "/world"]);
})
.then((list) => {
expect(list).to.have.length(2);
});
});
Error: a.attr is not a function
Don't wrap the el. If you do, it becomes a Cypress command which is always async.
You would have to do
cy.wrap(el).find("a").then(a => {
expect(a.attr("href")).to.be.oneOf(["/hello", "/world"]);
})
But find works for jQuery as well.
const a = el.find("a")
expect(a.attr("href")).to.be.oneOf(["/hello", "/world"]);
The problem is you're storing the results of a Cypress (Promise-like) Chainable. Also using an expect inside each won't benefit from the retry-ability provided by should.
it("should have ..... ", () => {
cy.get("ul > li")
.should("have.length", 2)
.each(($el) => {
cy.wrap($el)
.invoke("text")
.should("be.oneOf", ["hello", "world"])
cy.wrap($el)
.find("a")
.invoke("attr", "href")
.should("be.oneOf", ["/hello", "/world"])
});
});

Blank page after running Cypress tests

Whenever I run a new cypress test, the page that is supposed to show the UI is blank. Even when I click on each part of each test it remains blank. Please see image below.
image
Cypress package version: 10.4.0
Node v16.16.0
Code:
describe("home page", () => {
beforeEach(() => {
cy.visit("http://localhost:3000")
})
context("Hero section", () => {
it("the h1 contains the correct text", () => {
cy.getByData("hero-heading").contains(
"Testing Next.js Applications with Cypress"
)
})
it("the features on the homepage are correct", () => {
cy.get("dt").eq(0).contains("4 Courses")
cy.get("dt").eq(1).contains("25+ Lessons")
cy.get("dt").eq(2).contains("Free and Open Source")
})
})
context("Courses section", () => {
it("CourseL Testing Your First Next.js Application", () => {
cy.getByData('course-0')
.find('a')
.eq(3)
.contains('Get started')
})
})
})
/// <reference types="cypress" />
Cypress.Commands.add('getByData', (selector) => {
return cy.get(`[data-test=${selector}]`);
});
I faced the same issue in Cypress version 12.0.0 and I solved it by adding this configuration to cypress.config.js
testIsolation: false,
Try adding 's' to http; this might solve that else here is similar issue reported which might give you clue to your problem https://github.com/cypress-io/cypress/issues/4235
You might have put the it() describe() statements in the wrong place. Try creating the most simple test file possible or better still use an example test that cypress provides strip it down and continue to test it until it is barebones.
I have a "solution" in my tests - it seems that the it steps lose the URL.
Remove all the it steps:
describe('Register Native', () => {
// it("Verify1", () => {
: a
// })
// it("Verify2", () => {
: b
// })
})
Now I have a structure like this (only one it step):
describe('Registrer Native', () => {
it('Whole test- Without IT parts', () => {
: a
: b
: c
})
})
It is not an optimal solution as I now have a long test without intermediary it sections.

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()
});

Suppress global ajax in kendo autocomplete MVC

I have a kendo autocomplete box, which is bound to remote data.
whenever i type into the search box, my default Ajax loading animation is pop outs
i did some googling and found-->>> this
which says to include global: false in read to suppress this global ajax behavior
how can this be done in MVC wrapper?
#(Html.Kendo().AutoComplete()
.Name("productAutoComplete")
.DataTextField("ProductName")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetProducts", "Home");
})
.ServerFiltering(true);
})
)
I'm using the same scenario. After searching the internet for hours only answer on my hand was "You can't do it with wrappers. You have to initiate the autocomplete by js." But then I saw another solution for another product which make sense.
Here's what I did for my project:
In main js file;
var ajaxStartActive = true;
$(document).ajaxStart(
function () {
if (ajaxStartActive)
$loading.show();
}).ajaxStop(
function () {
$loading.hide();
});
Using with AutoComplete;
#(Html.Kendo().AutoComplete()
.Name("productAutoComplete")
.HtmlAttributes(new { onfocus = "ajaxStartActive = false;", onblur = "ajaxStartActive = true;" })
.DataTextField("ProductName")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetProducts", "Home");
})
.ServerFiltering(true);
})
)
I hope it helps

Resources