New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serenity/JS should provide a way to pass custom scroll options to the scrollIntoView()
method
#2000
Comments
I like this idea! However, some differences across the supported web integration tools make the implementation a bit more challenging. You can see the first attempt at implementing this feature at #1235 Happy to guide you through raising a PR if this feature is something you'd like to pick up. |
Indeed, I'm interested in working on this. I would greatly appreciate your guidance in creating a custom interaction that mirrors the Click activity. This will allow me to explore and experiment with the scrollIntoView behavior within this custom activity, which I'll refer to as "CustomClick." |
Serenity/JS interactions that accept custom configuration or overrides typically have a await actor.attemptsTo(
Send.a(GetRequest.to('/books/0-688-00230-7').using({ headers: { ... } }),
) You might want to consider something like this: Scroll.to(pageElement).using(configuration) However, some differences between WebdriverIO, Protractor and Playwright might make deciding how this interaction should behave tricky. For example:
Another interesting challenge is that the Following that design could make Serenity/JS interaction look awkward: Scroll.to(pageElement).using(true) // meh However, since Scroll.to(pageElement).using(Scroll.Top)
// where Scroll.Top == `{block: "start", inline: "nearest"}` Alternatively, we could have alias methods on Scroll itself: Scroll.toTopOf(pageElement)
// alias for Scroll.to(pageElement).using({block: "start", inline: "nearest"}) |
Hi @jan-molak, The problem is that scrollIntoView places the target element at the top of the page. Consequently, the element I want to click on gets positioned behind a navigation bar, and the click action is intercepted by two overlapping elements. |
Certainly, you can use script injection: import { Answerable, d, Interaction } from '@serenity-js/core'
import { BrowseTheWeb, PageElement } from '@serenity-js/web'
const ScrollToTopOf = (pageElement: Answerable<PageElement>) =>
Interaction.where(d`#actor scrolls to top of ${ pageElement }`, async actor => {
const element = await actor.answer(pageElement);
const page = await BrowseTheWeb.as(actor).currentPage();
await page.executeScript(
function scrollIntoView(nativeElement: any) {
nativeElement.scrollIntoView({block: "start", inline: "nearest"});
},
element,
)
}) |
@jan-molak Would you mind providing clarification regarding the term 'field' in the code snippet you shared? My goal is to ensure that when the scrollIntoView method is employed, the element is centered within the viewport. |
Sorry, it was a typo; I've updated the original snippet. |
However, @jan-molak , this approach won't be sufficient for overriding the class Click extends PageElementInteraction_1.PageElementInteraction {
/**
* Instantiates this Interaction.
*
* @param pageElement
* The element to be clicked on
*/
static on(pageElement) {
return new Click(pageElement);
}
constructor(element) {
super((0, core_1.d) `#actor clicks on ${element}`);
this.element = element;
}
/**
* @inheritDoc
*/
async performAs(actor) {
const element = await this.resolve(actor, this element);
await element.scrollIntoView(); // I'm interested in customizing this scrolling behavior within the Click interaction
await element.click();
}
} In this code, I'd like to emphasize my intent to customize the scrolling behavior within the Click interaction, which is not achievable using the previous approach. How should I proceed? |
const MyClick = (pageElement: Answerable<PageElement>) =>
Interaction.where(d`#actor clicks on ${pageElement}`, async actor => {
const element = await actor.answer(pageElement);
// note no scrolling
await element.click();
})
const MyScrollAndClick = (element: Answerable<PageElement>) =>
Task.where(d`#actor clicks on ${ element }`,
Scroll.toCentreOf(element), // as discussed previously
MyClick(element),
) Another alternative is to:
|
Yes, it works. Thanks @jan-molak 😄 |
What's the problem you're trying to solve?
The current functionality of
scrollIntoView()
places a page element at the top of the page. However, specific scenarios, like when a navigation bar overlaps the page's header section, can result in unintended consequences. In such instances, usingscrollIntoView()
may lead to the element being hidden by the navigation bar. As a consequence, when trying to click on the element, the click action could be intercepted by elements within the navigation bar. This predicament arises due to the absence of an option to customize scroll behavior within the method.This scenario introduces difficulties in Serenity/JS interactions, as the default scrolling behavior can impede efficiency. More precisely, the element may not become accessible for interaction during the screenplay, leading to unsuccessful tasks and eventual test failures.
How would you like to solve it?
Offering users the capability to specify custom scroll options for the
scrollIntoView()
method, akin to what's available in other automated testing frameworks, stands as the favored solution. These options can be drawn from the MDN documentation.Introducing comparable methods found in other testing frameworks would greatly benefit Serenity/JS. Furthermore, maintaining functionality closely aligned with native JavaScript would be an added advantage. Users of the framework would likely feel more at ease and accustomed to working with Serenity/JS.
Are there any alternatives?
I experimented with several alternative approaches but was unable to attain the desired outcome through any of them. Additionally, I'm interested in having the capability to craft custom activities, which would allow me to extend the functionality of the Click activity and experiment with modifying the behavior of the
scrollIntoView
method.How can we make it happen?
The text was updated successfully, but these errors were encountered: