Webdriver IO - Unable to find element with CSS selector with ID - webdriver-io

I am writing a simple WDIO selector with following statement. I was able to uniquely idenitfy it in browser. Not sure why WDIO was not able to set the value.
Given(/^I am on the login page$/, function () {
browser.url('https://secure-sandbox.modulrfinance.com/')
browser.maximizeWindow()
});
When(/^I enter password as \"([^\"]*)\"$/, function (password:string) {
//const txt_username = $('#username-inp')
//const txt_password = $('#password-inp')
$('#username-inp').setValue('')
$('#password-inp').setValue(password)
});
Then(/^I should see a flash message under username saying \"([^\"]*)\"$/, async function () {
const banner = await $('#.ng-star-inserted')
expect(banner).toHaveText('This field is required1')
});```
**error**
**[0-0] error: 'no such element',
[0-0] message: 'no such element: Unable to locate element: {"method":"css selector","selector":"#password-inp"}\n'** +

Seems like you are testing Single Page Application written in angular. You have to deal with the asynchronous behavior of Angular, by adding appropriate waits(Implicit, Explicit or Fluent waits).
Check this example.

Related

How can i click the following Button with puppeteer?

I'm trying to click a button on a website with puppeteer but it doesn't work for me.
Element-info:
<button aria-label="Alles akzeptieren" role="button" data-testid="uc-accept-all-button" class="sc-gtsrHT gqGzpd">OK</button>
My Code:
async function checkout(){
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto(product_url);
await page.waitFor(3000);
await page.click("Button[class='sc-gtsrHT gqGzpd']", elem => elem.click());
}
Error Message:
Error: No node found for selector: Button[class='sc-gtsrHT gqGzpd']
at Object.assert (C:\Coding\Ticket-Bot\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:26:15)
at DOMWorld.click (C:\Coding\Ticket-Bot\node_modules\puppeteer\lib\cjs\puppeteer\common\DOMWorld.js:277:21)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async checkout (C:\Coding\Ticket-Bot\bayern.js:14:5)
Pictures:
https://i.stack.imgur.com/BYOnx.png (Button Info)
https://i.imgur.com/of9Rjgo.png (Button)
what is the correct code so that the button will be clicked?
You get the error due to the element does not exist on the page, it may be caused by the fact that CSS classes are autogenerated as #Sirko suggests.
You can even inspect the element's class name in DevTools if you launch puppeteer in headful mode.
You will need to find those selectors that will remain the same, e.g.:
await page.click('[aria-label="Alles akzeptieren"]');
await page.click('[data-testid="uc-accept-all-button"]');
Note: I am not sure if you need elem => elem.click() in the click options.

Aurelia-testing: Failed to execute 'replaceChild' on 'Node': parameter 1 is not of type 'Node'

I am using for the first time the aurelia-testing package to test my HTML code.
I seem to have followed the docs to set up my test as follows:
describe('Contextual Menu HTML View test suite', function () {
let component: ComponentTester;
beforeEach(function () {
component = StageComponent
.withResources('../../src/components/modal/contextual-menu')
.inView('<contextual-menu is-active.two-way="activateMenu"></contextual-menu>')
.boundTo({ activateMenu: false });
});
it('should not add the is-active class to the root element', async function () {
await component.create(bootstrap);
const rootElement = await waitForDocumentElement('.qa-contextual-menu');
expect(rootElement.classList.contains('is-active')).toBe(false);
});
afterEach(function () {
component.dispose();
});
});
I tried using just bind instead of two-way but that fails too.
I tried both with a document.querySelector and with waitForDocumentElement, both cases fail, but anyways I assume the error comes from earlier.
I am getting an error and I am not sure why. Could you put on the tracks to identify the root cause of the following:
TypeError: Failed to execute 'replaceChild' on 'Node': parameter 1 is not of type 'Node'.
at Object.convert (/Users/lemoustachiste/work/lm-frontend/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/generated/Node.js:573:11)
at HTMLDivElement.replaceChild (/Users/lemoustachiste/work/lm-frontend/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/generated/Node.js:292:31)
at NodeJsDom.replaceNode (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-pal-nodejs/dist/nodejs-dom.js:95:29)
at makeElementIntoAnchor (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2432:19)
at applyInstructions (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2479:17)
at ViewFactory.create (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2707:7)
at TemplatingEngine.enhance (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:5290:24)
at /Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-framework/dist/commonjs/aurelia-framework.js:176:28
at new Promise (<anonymous>)
at Aurelia.enhance (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-framework/dist/commonjs/aurelia-framework.js:174:12)
Thanks a lot
I am not a jest user. So I simply used the scaffolded TS jest skeleton app from aurelia-cli (au new jest-skeleton --unattended --select typescript,jest,vscode). And found that to be working.
It seems the you are missing the following configuration in your jest.config.js.
testEnvironment: "node",
After only adding that, the tests started working.

Setting attribute via a ClientScript not persisting

My fixture has a ClientScript that sets an attribute on an element (the element comes from the script doing a document.querySelectorAll(...)):
element.setAttribute("data-foo", 'foo');
Later in testcafe-land when I try to access that element using a Selector it's always null:
const element = await Selector('[data-foo="foo"]')();
I've stuck a debugger statement into my injected ClientScript and as I step thru the function I see the element does indeed get the attribute added but as soon as I let the execution continue and try to find it again in the devtools Console the attribute is gone from the element.
I -think- it has to do with the iframe/shadow DOM? testcafe is creating? I see there is a sub-iframe/execution context in chrome devtools - my ClientScript is being injected into window.top but there is a testcafe-created iframe in the mix too.
ANY THOUGHTS how I can get this to work? I want an injected script to manipulate the DOM (by adding an attribute) that later on I want a testcafe Selector to select. Why doesn't this work and how can I get it working???
thanks!!!
Mark
TestCafe injects custom scripts into the head tag. These scripts are executed before DOM is loaded.
Here is an example of how to manipulate DOM using the client script:
import { Selector } from 'testcafe';
const scriptContent = `
window.addEventListener('DOMContentLoaded', function () {
var p = document.querySelector('p');
p.setAttribute("data-foo", 'foo');
});
`;
fixture `My fixture`
.page('https://devexpress.github.io/testcafe/example/')
.clientScripts({ content: scriptContent });
test('My test', async t => {
const el = await Selector('[data-foo="foo"]');
await t
.expect(el.textContent).eql('This webpage is used as a sample in TestCafe tutorials.');
});

problem accessing elements using id/name for login form in cypress

I am trying to login to a form written in angular js but cypress throws the following exception:
Uncaught TypeError: $(...).materialScrollTop is not a function
This error originated from your application code, not from Cypress.
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.
https://on.cypress.io/uncaught-exception-from-application
This is the cypress login code:
context('TestLogin', () => {
it('Test Login', () => {
cy.visit('url');
cy.get('input[id=Email]').type('email', {force: true});
cy.get('input[id=Password]').type('passcode', { force: true });
cy.get('button[type=submit]').click();
})
})
Since the login has a csrf token, I have used cy.request() as follows and I do get a response with status code 200 but when re-loading the site it goes back to login page.
describe("Tests for AntiForgeryToken", function () {
// variable from config, that contain Identity Server URL
const identityUrl = Cypress.config("identityServerUrl")
// command declaration that we are going to use in tests
// allows us to create request to server
Cypress.Commands.add("loginByToken", function (token, login, password) {
cy.request({
method: "POST",
failOnStatusCode: false,
url: `${identityUrl}/Account/Login`,
form: true,
body: {
email: login,
password: password,
__RequestVerificationToken: token,
RememberLogin: false
}
})
})
it("Should parse token from response body and return 200", function () {
cy.request(`${identityUrl}/Account/Login`)
.its("body")
.then((body) => {
const $html = Cypress.$(body)
// when the page is rendered
// we are trying to find the Request Token in the body of page
const token = $html.find("input[name=__RequestVerificationToken]").val()
// POST request with token and login data
// then we simply verify whether Indentity Server authorized us
cy.loginByToken(token, "test#test.com", "Test_1234")
.then((resp) => {
expect(resp.status).to.eq(200)
})
})
cy.visit(`${identityUrl}/Account/`);
})
Cypress documentation didn't provide much info about the exception.
Any insights from cypress experts are helpful.
As evident from the error, Cypress is failing the test as it found an exception in your application,this is not a cypress level exception but an uncaught exception in your app which is causing cypress to fail the test, this is pretty useful as you can check if its an actual error in your app and log it for the dev team to fix, check if you are able to reproduce this manually, either way i think the application code should be fixed to either fix the bug or catch the exception and return a valuable error message. If you want to disable this feature you can turn off all uncaught exception handling, so in your index.js or whatever file is the entry point add the following:
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
// you can also add a Debugger here to analyze the error
debugger;
return false;
});
not sure if turning this off will help as looks like there is something in your application which could be an issue, but this is just for informational purposes that you can turn this feature off if you needed to.
Here is the documentation for further reading : Cypress Events documentation
hope this helps

Cypress vue.js: CypressError "Timed out retrying: Expected to find content"

Problem description
CypressError: Timed out retrying: Expected to find content: 'mm'
within the element: but
never did.
I have mounted the component on cypress with mock data. Then I tried to get an element using below source code and receive the above error:
cy.get('#edit-highlights-form1').contains('2m');
Current situation
I have a vue.js application which contains a component and it consumes data from an API. Please find the source code below that I tried to write unit test for that component using Cypress.
Code:
describe('Edit highlights component ', () => {
beforeEach(mountVue({
template,
components,
data
}))
it('Stub the mock data to the component edit highlights', () => {
cy.server();
cy.route({
method: 'GET',
url: '/drupal/api/v1/getHighlightData/*',
response: data().highlightModel
}).as('apiHighligihtData');
mountVue({
template,
components,
data
});
cy.get('#edit-highlights-form1').contains('2m');
});
});
I got the tutorial from https://github.com/bahmutov/cypress-vue-unit-test/blob/master/cypress/integration/ajax-list-spec.js
I was not able to get the element #edit-highlights-form1 using the cypress command cy.get(). I solved this issue by using the command cy.get("#edit-highlights-form1").should( "have.value", '2m' );