How could I scroll one page to the right in Cypress?
E.g. I have a horizontally scrollable area. The area contains elements a, b and if I scroll to the right a and b get destroyed, while c and d get added.
My attempt is to find out the width of the scrollable view and then scroll that amount to the right. But the width does not get retrieved before the scrollTo gets called.
Here is what I am trying to do:
const width = cy.getCy("scroll-viewport").invoke("width");
cy.getCy("scroll-viewport").scrollTo(width, 0);
Your code sample has some mystery about it, for example what is cy.getCy().
I can show you how to do it with standard code, and you can adapt from there.
Assuming scroll-viewport is a selector for the scroll container (the owner of the scroll bar)
cy.get("scroll-viewport").then($scrollContainer => {
const width = $scrollContainer[0].offsetWidth;
$scrollContainer[0].scrollTo(width, 0);
})
Note $scrollContainer[0].scrollWidth gives you the total width after scrolling, in case you need that.
Related
I have a div that contains two element on top of each other :
one is a svg bar chart, where each bar is a rect with a data-test-id
the other one is an input range laying on top of the bar chart, offsetted so that the range length matches the chart width. It covers the whole graph so that receives any click event on the graph. Its opacity is set to 0.01
Here is what it looks like :
When I click on bar matched by a test-id in a cypress, I would like it to update the range value, as it works in a standard browser.
However it does not. If I try to cy.click on my rect, it does not work because it only tries to click on the rect.
I tried computing the x, y position to click on the range input but it does not work sadly :
cy.get("[data-test-id='2021-07-28T05:56:00Z']")
.as("targetBar")
.then(() =>
cy.get('[data-test-id="conversations-offset-cursor"]').as("cursor")
)
.then(() => {
const targetOffset = this.targetBar.offset();
const cursorOffset = this.cursor.offset();
const top = targetOffset.top - cursorOffset.top;
const left = targetOffset.left - cursorOffset.left;
cy.get('[data-test-id="conversations-offset-cursor"]').click({
x: top,
y: left,
force: true,
});
return cy.wait(10000);
});
But while the click is registered, and the x y coordinates seem relevant, it's as if I didn't set any coordinate at all. Here is the coordinates passed to the .click:
click 19.646743774414062 867.7333374023438
And here is the click log :
EDIT : I had mixed x and y coordinates, it clicks at the right place now, but still not triggering the event of the slider
I want to put the same legend top center of the chart. Legend items will be dynamic, likes sometimes 2,5 or 9, etc.
So, it should take space dynamically like how it is acting on the bottom.
I tried with inset functionality but it seems this is not looking better like the bottom one.
and there are few more complexity like I want it like a flat, so now if I define step size 3 then maybe, for now, it looks good for 9 items. but when there will be 2 items, it will show as a list!!
Although I solved that problem through the following solution:
// get parent elements
let parentEle = d3.selectAll("#chartID svg");
let childrenEle = parentEle
//Convert selection to selection representing the children
.selectAll(function () { return this.childNodes; })
.filter('g');
// putting legends position on TOP
d3.select(childrenEle._groups[0][2]).attr('transform', 'translate(0, 5)');
you have to keep eye on chart width - height and according to this, you may have to control padding in TOP for the chart.
might be this is not a good solution but it works fine for me :D
I've got a Xamarin Forms cross-platform application (iOS and Android), and on one of the screens I want a list with details:
Heading 1
Detail 1
Detail 2
Detail 3
Heading 2
Detail 1
Heading 3
Detail 1
Detail 2
As you can see, the amount of detail under each heading is variable.
I want the page to display at first with just the headings:
Heading 1
Heading 2
Heading 3
And then when the user presses on a heading, the details for that particular heading appear. Pretty standard stuff.
I've tried several different ways to get this to work, the only path that seems open to me is to have a StackLayout where I define a bunch of labels:
new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
new Label { Text = "Heading 1" },
new Label { Text = " Detail 1\n Detail 2\n Detail 3", IsVisible = false },
new Label { Text = "Heading 2" },
new Label { Text = " Detail 1", IsVisible = false },
new Label { Text = "Heading 3" },
new Label { Text = " Detail 1\n Detail 2", IsVisible = false }
}
}
I then add a TapGestureRecognizer to the heading labels, and when tapped I toggle the value of IsVisible for the detail labels. It works!
The only thing I don't like, is that there is no transition. I click on the heading label and BAM the detail label appears (correctly pushing down all the following labels to make space for itself). I would like an animation so that when I click on the header, the space beneath the header "slowly" opens up to reveal the detail.
As I read about animations online, one possibility is to set the HeightRequest of the detail labels to zero (instead of hiding them with IsVisible=false) and then creating an animation that "slowly" changes the HeightRequest from zero to the actual height of the label. And that's where I run into a problem.
I can't figure out how to get Xamarin to tell me the height of my "details" label.
If I inspect the Height and HeightRequest properties of my details label right after creating it, they are both -1 (no big surprise there). If I inspect those same two properties when I click on the heading, they are still -1. The only way I've found to get the height of my detail label, is to set the detail label visible, call ForceLayout() on my stack layout, store the detail label height, and then set the detail label invisible again. The problem with that is that I sometimes see the detail label flash visible for an instant while I do this.
What's the best/recommended way to accomplish my desired UI?
You can use the Animation API.
Read the blog about it - Creating Animations with Xamarin.Forms.
In particular for your scenario you can use the FadeTo method to animate the Opacity property of a Visual Element.
Eg :
await image.FadeTo (1, 4000);
For more information, see Animation.
In your case my suggested approach would be for showing a label, to set opacity of label to 0, then make it visible, and then use FadeTo to make the opacity to 1.
Use the opposite to hide the label, set opacity 0 via FadeTo, then set IsVisible to false.
If I understand right your problem the only thing you need is to avoid the flash on the label, if this is the case then you can set the Opacity to 0, in this way the label will not be visible until you set again the opacity to 1.
I can suggest you to make a custom XF control (to use as item DataTemplate) as follow:
2 vertical parts:
The header part (A) (when you click on it it will show the second part)
The second part is a 'Listview' control (B) that is empty at the beginning
When you click on (A):
it will show (B)
It will start to populate (B) with your details elements
The trick in my mind is to implement a method that populate the listview (B) item by item (getting them from your viewmodel) with some delay (a few milliseconds) between each insertion and maybe a 'fadeTo' effect too in the same time.
You can see here what I mean (see the "Fade" section):
Insert / fade list item effect sample in HTML
You can improve your template as you want, by embedding the two parts into a 'border' for instance, to make a graphical separation...
Tell me if it's unclear, all you need is time :)
And maybe if you are ready, you can try to make native controls / animations...
I was using apple's scrollview sample code PhotoScroller for my app using numerous images (and by recycling logic)
in UIScrollView. I implemented that in my app and it works fine.
Now Im working in an app similar to the above, but with the
difference, loading images in grid like view. When I happen to use the
same sample code, every thing works fine except the recycling logic.
I think there is some problem with my frame set which don't tell the
xcode, the visible region.
Please some one temme how to set the visible set for the grid View
structure for scrollview? The code I use is,
CGRect visibleBounds = _scrollView.bounds;
// CGRect gridElementvisibleBounds = CGRectMake(0, 0, 212, 200);
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) -
CGRectGetWidth(visibleBounds));
int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) -
CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex = MIN(lastNeededPageIndex, [self imageCount] - 1);
where _scrollView is the UIScrollView instance that I use and the
gridElement that I use is of frame size (0, 0, 212, 200). The number
of grid elements that occupy the scrollView bounds is
3 x 3 (9).
I don't want to use grid like tableViews(AQGridView, etc,.) since Im gonna load more than 500 images.
Please some one help me finding out the thing that I should correct in
the above code.
I nearly fixed the issue by making use of contentOffset to get the visible area.
Here is the piece of code illustrating what I did to make it working.
int firstNeededPageIndex = ((int)_scrollView.contentOffset.y / 960) * 9;
int lastNeededPageIndex = ((int)_scrollView.contentOffset.y / 960) * 9 + 17;
where I found the visible area by getting the contentOffset.y/960 and got the firstNeededPageIndex as given above.
When the scrollview scrolls, the components of the page that is getting to hide contains 9 elements and the successive page(got by lastNeededPageIndex) that is getting to be visible contains no components.
Hence I made it visible by making 18 objects to the visible area while scrolling.
Hence the objects to be visible while scrolling became 0th object to 17th object.
And the result is whenever the scrollview scrolls, 18 components(0 to 17) in the visible area(got through contentOffSet ) are recycled.
I am using FabricJS to create an application. I am finding that scrolling a parent div/container offsets the selectable area of an object to the right in direct relation to amount scrolled.
So, if I have a canvas that is 1200x600 and a container div that is 600x600 and I add a rect to that canvas at 400, 120; when I scroll 200px, I can't click on the rect to select it. Rather, I have to move my mouse to 600, 120 (empty space) to get the cross bar and select the rect.
Not sure if this is known, or has a work around - but I would appreciate any help possible.
You'll have to modify FabricJs code to make it work.
The problem is in the getPointer function, if you search for it in all.js you'll notice the comment "this method needs fixing" from kangax.
A workaround can be substituting this function with
function getPointer(event) {
// TODO (kangax): this method needs fixing
return { x: pointerX(event) + document.getElementById("container").scrollLeft, y: pointerY(event) + document.getElementById("container").scrollTop };
}
where "container" is the wrapper div of you canvas. It's not nice, since you have to put the exact id, but it works.
Hope this helps.