How to scroll up and scroll down using TestCafe? - testing

How can I scroll up and scroll down using TestCafe?
I tried window.scroll(),
window.scrollTo()and throws an error window is not defined.

UPD:
In v1.14.0 and later versions, you can use the following scroll methods: t.scroll, t.scrollBy, and t.scrollIntoView.
Old answer:
In your case, you can create your own ClientFunction:
import { ClientFunction } from 'testcafe';
fixture `Fixture`
.page `https://github.com/DevExpress/testcafe`;
const scroll = ClientFunction(function() {
window.scrollBy(0,1500);
});
test(`test`, async t => {
await scroll();
await t.wait(1000);
});
The t.hover action example:
// scroll to the "#some-element-scroll-to" element
await t.hover(Selector('#some-element-scroll-to'));

I had similar issue on Mac and used following to scrollIntoView of a know element in the page.
import { ClientFunction, Selector } from 'testcafe';
const scrollIntoView = ClientFunction( (selector: Selector) => {
const element = selector() as unknown as HTMLElement;
element.scrollIntoView();
});
fixture`HTMLElement`
.page('https://example.com');
test('Scroll element into view', async t => {
const bottomOfPage = Selector('#bottom-div');
await scrollIntoView(bottomOfPage);
});
Reference : Type cast page elements

Related

How to do drag only without drop in Testcafe

So I have a scenario where I want to capture a popup element message whenever I drag one element to another element.
public async dragTransitiontToSegment(item: number, transitionName: string) {
const _tailSegment = Selector('.rolling').nth(item);
const _transitionPanel = Selector('.effects-selector.editor-panel .item-container')
const _transitionType = _transitionPanel.withText(transitionName);
await t.click(_transitionPanel);
await t.dragToElement(_transitionType,_tailSegment,{speed:0.01});
}
Right now I've change the speed for the drag but it was still to fast to capture the message I want, because the dragToElement fucntion will drop it. Is there a way to just drag and hold it ?
at present, TestCafe doesn't allow you to drag without drop out of the box. You can simulate the sequence of events (the mousedown, mousemove, or HTML5 drag events)
import { Selector, ClientFunction } from 'testcafe';
function triggerMouseEvent (selector, type, options) {
const dispatchFunc = ClientFunction((type, options = {}) => {
options.bubbles = true;
options.cancelable = true;
options.view = window;
const event = new MouseEvent(type, options);
const targetElement = elementSelector();
targetElement.dispatchEvent(event);
}, { dependencies: { elementSelector: selector } });
return dispatchFunc(type, options);
}
fixture`Fixture`
.page`http://devexpress.github.io/testcafe/example`;
test('Test', async t => {
await t.click('#tried-test-cafe');
const slider = Selector('span.ui-slider-handle.ui-corner-all');
await triggerMouseEvent(slider, 'mousedown');
await t.wait(1000);
const offsetLeft = await Selector('.slider-value').withText('5').offsetLeft;
await triggerMouseEvent(slider, 'mousemove', { clientX: offsetLeft });
await t.wait(1000);
await t
.expect(slider.offsetLeft).gte(352)
.expect(slider.offsetLeft).lte(353);
});
Also, TestCafe 1.15 will include the t.dispatchEvent method that allows you to trigger events using TestController.

WebDriverIO : getText(), click() methods are not working - it says they are not function

HomePage:
class homePage {
get pageHeader() { return $('//h1[contains(text(),"Best")]'); }
get pagesubHeader() { return $('div.banner-text-content>p.sub-text'); }
get supportLink() { return $('//li/span[contains(text(),"Support")]') }
HomeElement Page:
const homePage = require("../Pages/homePage")
describe("Home Page Elements handle", function () {
it("Verify HomePage Elements", async function () {
// await browser.url('https://www.freshworks.com/');
let text =homePage.pageHeader.getText();
console.log(text);
})
})
Error:
Home Page Elements handle Verify HomePage Elements
homePage.pageHeader.getText is not a function
}
module.exports = new homePage();
You use async, so this tells me you are working with WebdriverIO Async mode. This means, all the functions will mostly return a promise.
So proper way of doing it is that you need to await for the browser/element functions:
const pageHeader = await homePage.pageHeader;
const text = await pageHeader.getText();
console.log(text);
Remember, $, $$ and basically any functions of the browser or of the element are promises in async mode, so essentially, you attempted to "getText()" or "click()" on a promise object.

Unit test jest enzyme throws error on Formik 'resetForm'

I am trying to run unit test (enzyme) throws error on Formik 'resetForm'.
TypeError: Cannot read property 'resetForm' of undefined
FormikForm.js
_handleSubmitPress = (values, { resetForm }) => {
const { onSubmit } = this.props;
if (onSubmit) {
onSubmit({ ...values, resetForm });
}
};
UnitTest.js:
it('Should fire formik form submit', () => {
const UpdateButtonPressMock = jest.fn();
const component = Component({
onSubmit: UpdateButtonPressMock,
});
expect(component.find(Formik)).toHaveLength(1);
component.find(Formik)
.first()
.simulate('Submit');
expect(UpdateButtonPressMock).toHaveBeenCalled();
});
I couldn't find any solution for this error.
Could someone help me on the above? I would really appreciate any help.
According to official docs for simulate, the function signature accepts an optional mock event.
The code you are testing uses properties that are not included in the default SyntheticEvent object that ReactWrapper passes to your event handler by default, for instance event.resetForm.
One way to do this is by triggering Formik's onSubmit directly like so:
// UnitTest.js
.simulate("submit", { resetForm: whateverYourMockResetFormValueShouldBe })
component.find(Formik)
.first()
.prop('onSubmit')(valuesMock, { resetForm: UpdateButtonPressMock });
expect(UpdateButtonPressMock).toHaveBeenCalled();
I haven't tested this, but you should be able to pass the event along with simulate as well.
// UnitTest.js
component.find(Formik)
.first()
.simulate("submit", { resetForm: UpdateButtonPressMock })
expect(UpdateButtonPressMock).toHaveBeenCalled();

vue-test-utils window scroll

Need some advice on how to test a window scroll event using vue-test-utils
Below is my js
export default {
created () {
window.addEventListener('scroll', this.bannerResize);
},
methods: {
topBResize () {
var header = document.getElementById('topB');
var pos1 = header.offsetTop;
var pageYOffset = window.pageYOffset;
if (pageYOffset > pos1) {
header.classList.add('sticky');
} else {
header.classList.remove('sticky');
}
}
}
}
Below is my unit test using vue-test-utils
import {expect} from 'chai';
import {createLocalVue, shallow} from 'vue-test-utils'
const localVue = createLocalVue()
localVue.use(VueRouter)
localVue.use(Vuex)
const wrapper = shallow(Banner, {
localVue,
router,
attachToDocument: true
})
describe('topB.vue', () => {
it('topB resize', () => {
wrapper.setData({ bsize: true })
const dBanner = wrapper.find('#topB')
wrapper.trigger('scroll')
const pageYOffset = 500;
const pos1 = 200;
expect(dBanner.classes()).contains('sticky')
})
})
The test fails when you check if the sticky class is added.
How do I test this method ? I would like to see the sticky class added when window scrolls vertically
Thanks,
RD
You're triggering a scroll event on the div#topB wrapper, but the event listener is on window. JSDom, used by Mocha and Jest, doesn't support the normal JavaScript methods of scrolling window via window.scrollTo/window.scroll, but assuming you mount the test instance with attachToDocument, you can still manually dispatch a scroll event with:
window.dispatchEvent(new CustomEvent('scroll', { detail: 2000 }))
Your event handler would have to parse the event detail for this value and fallback to window.pageYOffset.
// var pageYOffset = window.pageYOffset;
var pageYOffset = !Number.isNaN(e.detail) ? e.detail : window.pageYOffset;
see GitHub repro 1
Alternatively, you can assume the scroll-event handler would be called upon scrolling; and test by running the scroll-event handler (wrapper.vm.topBResize()) directly, and then checking for the expected outcome. You can set window.pageYOffset before running the handler:
window.pageYOffset = 1000;
wrapper.vm.topBResize();
expect(dBanner.classes()).contains('sticky');
wrapper.pageYOffset = 0;
see GitHub repro 2

Shadow DOM and testing it via Jasmine

I have a webcomponent that creates a shadow DOM and adds some html to its shadowRoot.
class SomeThing extends HTMLElement {
attachedCallback () {
this.el = this.createShadowRoot();
this.render();
}
render () {
this.el.innerHTML = '<h1>Hello</h1>';
}
}
export default SomeThing;
And I am compiling it with the help of webpack and its babel-core and babel-preset-es2015 plugins.
Also I am using Karma and Jasmine to write my Unit Test. This is what it looks like.
describe('some-thing', function () {
var someElement;
beforeEach(function () {
someElement = document.createElement('some-thing');
});
it('created element should match string representation', function () {
var expectedEl = '<some-thing></some-thing>';
var wrapper = document.createElement('div');
wrapper.appendChild(someElement);
expect(wrapper.innerHTML).toBe(expectedEl);
});
it('created element should have shadow root', function () {
var wrapper = document.createElement('div');
wrapper.appendChild(someElement);
expect(wrapper.querySelector('some-thing').shadowRoot).not.toBeNull();
})
});
I want to see if there is something in the shadowRoot of my element, and want to write test cases for the HTML and events created inside the shadowRoot. But the second test is failing. It is not able to add shadowRoot to the some-element DOM.
If anyone can help me out, that would be helpful.
I am also uploading the full test working project on Github. You can access it via this link https://github.com/prateekjadhwani/unit-tests-for-shadow-dom-webcomponents
Thanks in advance
I had a similar problem testing a web component but in my case I am using lit-element from polymer/lit-element. Lit-element provides life cycle hooks, template rendering using lit-html library (documentation).
So this is my problem and how I solved. I noticed that the component was added and the class executed constructor and I had access to public methods using:
const element = document.querySelector('my-component-name')
element.METHOD();
element.VARIABLE
But it never reached the hook firstUpdated, so I thought the problem was the speed the test executes vs the speed component is created. So I used the promised provided by lit-element API (updateComplete):
Note: I use mocha/chai instead of Jasmine
class MyComponent extends LitElement {
render() {
return html`<h1>Hello</h1>`
}
}
customElements.define('my-component', TodoApp);
let element;
describe('main', () => {
beforeEach(() => {
element = document.createElement("my-component");
document.querySelector('body').appendChild(element);
});
describe('test', () => {
it('Checks that header tag was added to shadowRoot', (done) => {
(async () => {
const res = await element.updateComplete;
const header = element.shadowRoot.querySelector('h1');
assert.notEqual(header, null);
done();
})();
});
});
});
So, my advice is create a promise and resolve it when the render function is executed, use the promise to sync the creation of the component with tests.
I am using this repository to test concepts
https://github.com/correju/polymer-playground