I have a code that scrolls a growing page to the bottom (until it's not possible to scroll to the bottom).
When it's not possible, it scrolls to the top and the javascript code is finished.
For example: imagine a timeline on facebook.
It's a growing page, so I can scroll it again and again until it's not possible to scroll (then I will be in: "BORN").
So this is my code:
while (i < elements.Count)
{
js.ExecuteScript("var timeId = setInterval( function() {
if(window.scrollY<(document.body.scrollHeight-window.screen.availHeight))
window.scrollTo(0,document.body.scrollHeight); else { clearInterval(timeId);
window.scrollTo(0,0); } },5000);");
i++;
}
I want to add 1 to i only when the setInterval is finished.
I tried the next thing:
while (i < elements.Count)
{
object a = js.ExecuteScript("setInterval( function() {
if(window.scrollY<(document.body.scrollHeight-window.screen.availHeight)) {
window.scrollTo(0,document.body.scrollHeight); return '1'}; else {
clearInterval(timeId); window.scrollTo(0,0); return '2'} },5000);");
while (a != '2') {
// do nothing, this while will be ended when we arrived the bottom and
// go back to the top
}
// all the page is loaded
i++;
}
but it doesn't work.. maybe there is a way to scroll to the bottom more and more and then to the top without using set interval? (but remember: it's a growing page that grows when you scroll it down and down..
How can I do it?
The setInterval function is asynchronous, meaning that it happens after the ExecuteScript function gets a return value, this is why what you tried didn't work. The best solution I can think of is to change a little bit the structure of your code and use C# Threading.
Using C# Threading
This way, what we are going to do is to each time stop the code for 5 seconds and then execute a JavaScript code that checks if you can scroll further down, if yes scroll down and if not scroll back up. This JavaScript code will also return whether we should continue running this loop or not.
Basically, this is the JavaScript code we will execute:
if (window.scrollY < (document.body.scrollHeight - window.screen.availHeight)) {
window.scrollTo(0, document.body.scrollHeight);
return true;
} else {
window.scrollTo(0, 0);
return false;
}
And this is how the overall C# code should look:
while (i < elements.Count)
{
bool run = true;
while (run)
{
System.Threading.Thread.Sleep(5000);
run = (bool)js.ExecuteScript("if(window.scrollY<(document.body.scrollHeight-window.screen.availHeight)){window.scrollTo(0,document.body.scrollHeight);return true;}else{window.scrollTo(0,0);return false;}");
}
i++;
}
find something to use as a variable for when you hit the bottom and then use an if statement in the While loop to increment i when that has happened
Related
I am automating interaction with a website where the user will have to refresh the pages n times manually (sometimes 3 or 5 or even longer) so that the buttons appear on the web page. To overcome this issue, I created a do / while loop that should refresh the page until the button is visible so it can be clicked. The problem is it goes out of sync and infinitely loops. I tried the script below, but it still doesn't stop refreshing. Any idea how to make it stop refreshing as soon as the element is visible? by default, the element will not be visible, so the user will have to refresh the page first. The refresh works, but it is very quick, and it doesn't give enough time to check the state of visibility of the button, and maybe that's why it goes into an infinite loop
int retries = 0;
bool isElementVisible = false;
do {
await Page.ReloadAsync(new PageReloadOptions() { Timeout = 5000 });
isElementVisible = await Page.IsVisibleAsync("input[name='elementname']");
retries ++;
while (!isElementVisible)
The problem with your code is that IsVisibleAsync will resolve to false immediately.
You could wait for visible with some timeout using WaitForSelectorAsync. For instance, 5 seconds:
int retries = 0;
bool isElementVisible = false;
do {
await Page.ReloadAsync(new PageReloadOptions() { Timeout = 5000 });
try {
// The default State is Visible
await Page.WaitForSelectorAsync("input[name='elementname']", new(){ Timeout = 5000});
isElementVisible = true;
} catch(Exception ex) {
retries ++;
}
} while (!isElementVisible)
I tried to hide a text in Unity after caps was pressed, but it doesn't work, it stops before "while".
I'm quite a not up to par programmer, so anyone more experienced?
private float TurnOffInfoText()
{
bool IsCapsPressed = Input.GetKeyDown(KeyCode.CapsLock);
while (IsCapsPressed == true)
{
EndOfGameText.enabled = false;
}
return 0;
}
Why does this even return a value?
Also your while loop would completely freeze the entire App and even the Unity Editor application! Within the loop the IsCapsPressed value is never ever changed!
I don't see where your method is called from but if you never experienced a freeze so far then "luckily" the key never went down in the same frame so far.
Usually you would rather poll the input every frame. By a simple look into the API for Input.GetKeyDown:
private void Update ()
{
if(Input.GetKeyDown(KeyCode.CapsLock))
{
EndOfGameText.enabled = false;
}
}
I'm recording Coded UI Tests with VS 2012, which shall test the functions of a web application.
After I loaded the web page, I click on a button to start p.e. a job application.
After the next page has loaded on the same site, my problem begins.
The entry controls are at the end of the web site.
To take a look and input data into the entry controls, I must scroll down.
The recording produced the following method in the UIMap.
Designer.cs:
public void Scrollen()
{
#region Variable Declarations
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
this.UIGoogleMozillaFirefoxWindow.UIItemPropertyPage.UIBewerbungDemoFirmaDocument.WaitForControlExist();
this.UIGoogleMozillaFirefoxWindow.UIItemPropertyPage.UIBewerbungDemoFirmaDocument.WaitForControlReady();
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly;
WinControl uIBewerbungDemoFirmaDocument = this.UIGoogleMozillaFirefoxWindow.UIItemPropertyPage.UIBewerbungDemoFirmaDocument;
#endregion
// Click "Job application" document
Point pt = new Point(1390, 553);
int count = 0;
while (!uIBewerbungDemoFirmaDocument.TryGetClickablePoint(out pt) && count < 20)
{
count++;
System.Threading.Thread.Sleep(10);
if (count == 20)
Console.WriteLine("ClickablePoint not found");
}
Mouse.Click(uIBewerbungDemoFirmaDocument, new Point(1390, 553));
Mouse.MoveScrollWheel(10);
}
As You can see, I tried WaitForControlExist, WaitForControlReady, TryGetClickablePoint and the method MoveScrollWheel.
But neither Mouse.Click nor Mouse.MoveScrollWheel are working.
And in the next method, where I click into the first of the entry fields, I get a message at execution time, that the click event produces an error, because the control is hidden (because it's down below on the website, out of visible range).
After several tests this is making me crazy.
Any idea what has gone wrong and how can I scroll down the web site, so my entry controls are in visible range?
You can try Control.EnsureClickable(). Or you can use below mentioned function to scroll the page until the control is not clickable.
public static void ScrollAndClick(HtmlControl Control)
{
bool isClickable = false;
if (Control.TryFind())
{
while (!isClickable)
{
try
{
Control.EnsureClickable();
Mouse.Click(Control);
isClickable = true;
}
catch (FailedToPerformActionOnHiddenControlException)
{
Mouse.MoveScrollWheel(-1);
throw;
}
}
}
else
{
throw new AssertInconclusiveException("Control Not Found");
}
}
You can also add condition related to timeout to make sure it don't go to infinite loop.
Let me know if you are having issue with this at your end.
Hi Guys i'm trying to let my Screen blink a morse code out using timer , but no luck, can you spot any problem?
Sry but i feel sad for those who cant think out of the box and just mark a -2 without even understanding the situation.
Anyway, found about using await Task.Delay(100) but gridHalfFront.Opacity = 1; isnt being "activated" when its being read. not sure why.
async public void RunMorseCode()
{
foreach (char c in word.ToCharArray())
{
string rslt = Codes[c.ToString()].Trim();
foreach (char c2 in rslt.ToCharArray())
{
if (c2 == '.')
{
gridHalfFront.Opacity = 0;
await Task.Delay(100);
}
else
{
gridHalfFront.Opacity = 0;
await Task.Delay(1000);
}
gridHalfFront.Opacity = 1;
}
}
}
use System.Threading.Thread.Sleep(1000) and/or System.Threading.Thread.Sleep(3000) inside yr loop to make yr screen blink on and off
gridHalfFront.Opacity = 1;
if (c2 == '.')
{
System.Threading.Thread.Sleep(1000);
}
else
{
System.Threading.Thread.Sleep(3000);
}
gridHalfFront.Opacity = 0;
change it to the way it best for you, but dont use those timers
Your code is missing the Timer event handler. After calling Start() and after the elapsed time a Tick event from the Timer will be raised. There you have to change the opacity.
I think you are misunderstanding the use of a Timer. If you put the following code at the top of StartTimer you will see what I mean.
Console.WriteLine("Started {0}", inputTiming);
When you run you will get a bunch of timers are being created immediately. This is not what you want for two reasons. Firstly, they are all assigned to the same variable, so the second is 'logically' killing off the first, etc. Secondly, you don't want them created all at once, as all of the 1 second ones will all run at the same time after 1 second, and all of the 3 second ones will run together after 3 seconds. And, as already mentioned, to run code after the timer expires you need to hook up the event.
BIG EDITS Sorry didn't realise you were looking at Metro. What I have said above still holds, but I will back away from providing a solution.
Given the comments about Sleep() not working on Metro, I think you need to so all the code inside the timer for one character, and then set the interval for the next character from within the timer. Will provide some code in a few minutes...
Ok hi, I am making a program in Microsoft Visual Studio and every time I run it and and click start (I have a start button), it will do what I have it programmed to do, but the form always freezes and doesn't display what i want it too (it says "Not Responding" once i start it). It is good for doing it job, but I have things on the form that are supposed to be shown. While it keeps freezing, it does not give me the option to stop it, or show any labels I have set to change, during it's running. Any help on this will be appreciated. Thank You.
EDIT: This is what I have:
void CheckAll()
{
for (; ; )
{
CheckPixel();
Application.DoEvents();
}
}
It is constantly doing CheckPixel();, I take it that is the reason why it is freezing. There are never any breaks.
This usually means you are blocking the UI thread (e.g. running a long operation inside a button click handler). Instead of using the UI thread, you will generally need to offload long I/O operations to the ThreadPool or your own worker threads. This is not always easy to do and requires careful design and a good understanding of concurrency, etc.
Your application is freezing because it's in an infinite loop. I don't know how you can fix it, because I don't know exactly what you're trying to do here.
Update: since I need to go to bed, I'm going to toss out a total guess here. Your CheckPixel() method should probably have a signature like this:
public bool CheckPixel(int x, int y)
{
Color color = _myBitmap.GetPixel(x, y);
return (color == Color.Red);
}
where _myBitmap is a form-scoped Bitmap. Then your CheckAll() method should be something like this:
public bool CheckAll()
{
for (int x = 0; x < _myBitmap.Width; x++)
{
for (int y = 0; y < _myBitmap.Height; y++)
{
if (CheckPixel(x, y))
{
return true;
}
}
}
return false;
}
G'night folks! I'll be here all week.
Put your program in a try-catch block and then have any exception thrown print in a messagebox.
http://msdn.microsoft.com/en-us/library/0yd65esw%28VS.80%29.aspx
Also, try inserting a breakpoint at the point of click to identify where exactly it freezes up.
Instead of Application.DoEvents() why don't you replace with Threading.Thread.Sleep(0)? I'm not an expert but I prefer Thread.Sleep better then DoEvents.
You need to have some way of exiting out of the loop.
Either your for loop needs the logic to go from ? to ? (as in
for(int i = 0; , < 100; 1++)
which will will loop 100 times
OR
for(;;)
{
if(SomeCondition == true)
{
break;
}
}