for example,I try to locate the element in the webtour,see the html like this:
<frameset>
<frame name="a"></frame>
<frame name="b"><input name="login"/></frame>
</frameset>
and there is no id attribute,I try to use .frame(0).frame(1),but it didn't work,can somebody give me a little hint?Thanks
Nightwatch
With .frameParent you need to change focus on parent frame and then choose which frame you want to have focused:
this.testFrames = function (browser) {
browser
.frame(0) // first frame
.frameParent()
.frame(1) // second frame
.frameParent()
}
Docs: https://nightwatchjs.org/api/frameParent.html
Now, to fill the input field inside second frame:
this.testInputFrame = function (browser) {
browser
.frame(1) // second frame
.waitForElementVisible('input[name="login"]')
.setValue('input[name="login"], 'user123')
.frameParent()
}
Related
I'm using a Kendo ScrollView to display person images on a form.
Separate from the ScrollView, users can change the display order of the images. After they save their changes to the display order, the ScrollView is reloaded, scrolls to the first item, and should display the images in their new order.
However, I've noticed that when the ScrollView is currently on the first page, that page does not get refreshed/redrawn.
My ScrollView looks something like this:
#(Html.Kendo().ScrollView()
.Name("personImage")
.TemplateId("personImageTemplate")
.DataSource(d => d
.Custom()
.Type("aspnetmvc-ajax")
.Transport(t => t
.Read(r => r.Action("PersonImages_Read", "Person", new { personID = Model.ID } ))
)
.Schema(s => s.Data("Data").Total("Total"))
.ServerPaging(false)
.PageSize(1)
)
)
The template looks like this:
<script type="text/x-kendo-tmpl" id="personImageTemplate">
<img class="personImage"
src="#(Url.Action("ImageRender", "Person"))?imageID=#= data.ID #"
title="#= data.Filename #" />
</script>
And here is my refresh function:
function refreshPersonImageScrollView() {
var scrollView = $("#personImage").data("kendoScrollView");
if (scrollView) {
scrollView.dataSource.read();
// https://docs.telerik.com/kendo-ui/api/javascript/ui/scrollview/methods/refresh
// redraws, doesn't re-read from datasource
scrollView.refresh();
// scroll to first image
scrollView.scrollTo(0);
}
}
When I watch the requests being made when I call this function, I see this:
A. When a page other than the first page is selected:
PersonImages_Read (the ScrollView's dataSource read)
The ScrollView scrolls to the first image
3x ImageRender, as it renders the first 3 items in the ScrollView
B. When the first page is selected:
PersonImages_Read (the ScrollView's dataSource read)
Nothing else
I tried switching the order of scrollView.refresh() and scrollView.scrollTo(0), but the result does not change.
Is there any way to get Kendo to refresh/redraw the current page? I thought refresh would do it, based on the documentation, but it does not.
Edit
I've been able to replicate this issue in REPL. To see the behavior in action:
Note the "Rendered" time under the first image.
Scroll to the second image in the ScrollView.
Wait several seconds, then click the "Refresh" button.
The ScrollView should scroll back to the first image.
Observe that the "Rendered" time under the first image matches the "Last clicked" time reported below the "Refresh" button, and is no longer what it was in step #1. (This is the correct behavior.)
Remain on the first image for several seconds. Note the "Rendered" time listed before continuing.
Click the "Refresh" button.
Note that the "Last clicked" time has updated, and in the "Log" section, there is an entry that reads "dataSource read complete" at approx. the same time. However, the "Rendered" time under the image has not changed, and there is no log entry that says "image for product #X loaded".
I am using Kendo version 2021.3.1109 in my project. The Kendo version in the REPL above is 2022.3.913 and it still occurs in that version.
I have found a way to resolve the issue, but this may be worth opening a possible bug ticket with Telerik, because you would think that scrollView.refresh call would work.
What I changed in your refreshPersonImageScrollview function was to call setDataSource on the scrollview rather than calling the refresh method. Like so:
function refreshPersonImageScrollView() {
$("#refresh-last-clicked").text("Last clicked: " + getCurrentTime());
addToLog("refresh button clicked");
var scrollView = $("#personImage").data("kendoScrollView");
if (scrollView) {
scrollView.dataSource.read();
scrollView.setDataSource(scrollView.dataSource);
// scroll to first image
scrollView.scrollTo(0);
}
}
This appears to force the scrollView to re-evaluate its life choices and properly refresh :) However, it does seem to trigger additional dataSource reads, so it's not ideal.
One other thing I tried that didn't resolve the problem, but may be a good thing to change to anyway, would be to utilize the promise returned by the dataSource.read call. Meaning, do your scrollView setDataSource and scrollTo calls after the dataSource read promise is settled, like so:
scrollView.dataSource.read().then(function() {
scrollView.setDataSource(scrollView.dataSource);
// scroll to first image
scrollView.scrollTo(0);
});
REPL link here
I got a basic WebView in Xamarin.Forms like this:
<WebView AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" x:Name="ChartWebView" Style="{StaticResource BackgroundStyle}">
<WebView.Source>
<HtmlWebViewSource Html="{Binding ChartHTML}" />
</WebView.Source>
</WebView>
I use the WebView to display a Chart.js diagram which works perfectly fine. On my page i got a button where the user can request data.
private async Task RequestData()
{
//Doing some stuff to get data ...
BuildChartHTML();
}
private void BuildChartHTML()
{
var html = GetChartJSConfigString();
Device.BeginInvokeOnMainThread(() =>
{
ChartWebView.Source = new HtmlWebViewSource
{
Html = html
};
});
}
However, on iOS only, everytime on exactly the 10th request/reload the WebView gets blank. It also stays blank after that. I need to re-navigate to this page to get it up and running again. I tried adjusting the height on WebView.Navigated as described in this thread, without success.
The problem doesn't accure on Android with the same code base.
Open to any workarounds if this is a framework bug.
PS: I obviously made sure that the html I'm loading is not broken. I loaded the same data 10 times and i compared the html loaded on the 10th time where the WebView broke. It was exactly the same HTML string.
Turned out to be a problem with iOS WKWebView and the use of HTML canvas (chart.js is renderered on a canvas).
After debugging into my WebView (stupid me not thinking about that possiblity before), i found out that the canvas memory exceeded the limit. With the help of a solution posted here i managed to avoid this problem.
Keep in mind this solution is a little bit hacky. Basically what I've done is, as pointed out in the link above, i "deleted" the canvas everytime i reload my chart. By "deleting" i mean setting the canvas to width and height to zero. Applied to my code the solution looks like this:
Inside my javascript that runs in the browser i added a function like this:
function deleteCanvas() {
//Get the main canvas where the chart is rendered to
var chart = document.getElementById('chart');
chart.height = 0;
chart.width = 0;
}
And then everytime i call my BuildChartHTML() function i call this method in my c# code like this:
Device.BeginInvokeOnMainThread(() =>
{
ChartWebView.Source = new HtmlWebViewSource
{
Html = html
};
ChartWebView.Eval("deleteCanvas()");
});
I'm using this scroll bar from idiotWu which works great so far:
https://github.com/idiotWu/react-smooth-scrollbar
What I need to do next is in my react project, I need to programatically change the scroll position. In my project, when my fires reactComponent.render() again because of some things I'm doing, I need to scroll back to the top of the <Scrollbar />. I don't see in the documentation any mention of how to do something like a element.scrollTop() or <Scrollbar scrollPosition={0} />.
I tried to manually set the transform translate3d of <div class="scroll-content">, but that didn't work because the scrollbar is saving it's scroll position value somewhere, and I don't know how to access it.
How do I reset the scroll to the beginning? Alternatively, how do I state the scroll position?
EDIT
I also tried each of these but they all did not produce the results I wanted
export default class MyClass extends React.Component {
render() {
document.getElementById('panel').setPosition(0,0); // setPosition is not a defined method
document.getElementById('panel').scrollTop=0; // had no effect
scrollbar.setPosition(0,0); // scrollbar not defined
scrollbar.scrollTop=0; //scrollbar not defined
return (<Scrollbar id="panel">stuff</Scrollbar>);
}
}
Try scrollbar.scrollTop = 0 or scrollbar.setPosition(scrollbar.offset.x, 0).
I want to reduce them to a maximum 200px width and keep the same layout with the 10px spacing the photos have. Also I don't want to style the posts to be that wide and use overflow:hidden that will only cut off the photosets.
jQuery Solution
For this solution you will need the latest version of jQuery and the jQuery plugin imagesLoaded included in the head of the theme before the following:
<script type="text/javascript">
$(document).ready(function() {
$('iframe.photoset').each(function() {
var i = this;
$(i).attr("onload", "ps_resize(this)");
var s = $(i).attr("src");
s = s.replace(/\/500\//, "/200/");
$(i).attr("src", s);
});
});
function ps_resize(i) {
$(i).contents().find("body").imagesLoaded(function() {
$(i).attr("width", 200);
$(i).attr("height", $(this).height());
});
return false;
}
</script>
What Solution Does
When the DOM is ready, find all the photoset iFrames
For each iFrame...
set the "onload" attribute to your frame resizing function
get the frame's source url, change the size (e.g. 500) to 200
set the frame's source url (this will cause it to reload with a smaller photoset)
In the resizing function...
wait for the images to load
set the frame width to 200
set the frame height to the new height of the photoset
Additional Code for Infinite Scroll
If you are using the Infinite Scroll jQuery Plugin, you will need to additionally include this in your success callback function:
...
$(newElements).find('iframe.photoset').each(function() {
var i = this;
$(i).attr("onload", "ps_resize(this)");
var s = $(i).attr("src");
s = s.replace(/\/500\//, "/200/");
$(i).attr("src", s);
});
...
Obviously, if you're using Infinite Scroll, I would suggest defining a function that is called on each iFrame on both the initial load and the scroll so you don't have repeated code to maintain.
I'm wondering why the following code doesn't work, where "banner" is the css class of each of four different divs. The resulting page displays all images for one second, and then they all vanish.
<script type="text/javascript">
var bannerArray = new Array();
bannerArray = $$(".banner");
bannerArray.each(function (b) {
b.hide();
});
bannerArray.each(function (b) {
b.show();
Element.hide.delay(1, b.id);
});
</script>
delay doesn't delay all code execution. It only delays the invocation of a specific function; the rest of your code gets executed right away, while the delay is counting down in the background. So you're setting a "hide timer" for each element at the same time. Since they all have the same 1-second delay, they all fire 1 second after being set.
Try this instead
(function() { // wrap everything in a function to avoid polluting the global namespace
var banners = $$('.banner'); // no need to create an empty array first
banners.invoke('hide'); // no need to use each
function showNextBanner() {
banners.last().hide(); // hide previous banner
banners.first().show(); // show next banner
banners.push(banners.shift()); // first element moves to become last element
showNextBanner.delay(1); // set a timeout to show the next banner
}
showNextBanner(); // start the banner rotation/looping
}());
Here's a demo