public static IWebElement WaitGetElement(IWebDriver driver, By by, int timeoutInSeconds, bool checkIsVisible = false)
{
WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds((double)timeoutInSeconds));
IWebElement result;
try
{
if (checkIsVisible)
{
result = webDriverWait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(by));
}
else
{
result = webDriverWait.Until<IWebElement>(ExpectedConditions.ElementExists(by));
}
}
catch (NoSuchElementException)
{
result = null;
}
catch (WebDriverTimeoutException)
{
result = null;
}
catch (TimeoutException)
{
result = null;
}
return result;
}
This is My Code . It Give Me Erro : The name 'ExpectedConditions' does not exist in the current context .
Can you Help Me .
I Think you are missing this particular Nuget package "SeleniumExtras.WaitHelpers.ExpectedConditions"
https://www.nuget.org/packages/DotNetSeleniumExtras.WaitHelpers/3.11.0
You can download it from nuget library or with the link provided. Later as some comments tell you must put an "using" in the code.
I hope this helps
Related
Given I need wait for one textbox appears, do something, and later I will need wait another Textbox.
I want to know if this code is correct:
var waitForTextBox = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
waitForTextBox.Until(ExpectedConditions.ElementIsVisible(By.Id("txtFirstName"))).SendKeys("John");
waitForTextBox.Until(ExpectedConditions.ElementIsVisible(By.Id("txtLastName"))).SendKeys("Skeet");
or if instead of reusing waitForTextBox, I will need do like this:
var waitForFirstName = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
waitForFirstName.Until(ExpectedConditions.ElementIsVisible(By.Id("txtFirstName"))).SendKeys("John");
var waitForLastName = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
waitForLastName.Until(ExpectedConditions.ElementIsVisible(By.Id("txtLastName"))).SendKeys("Skeet");
Reusing the WebDriverWait objects for multiple "waits" is best. The only time you need a different WebDriverWait object is if you need two different timeout periods. Otherwise the only state that a WebDriverWait keeps is the driver and how long it waits.
Ok, I found the source code for the WebDriverWait and Until method, and I find there is no problem reusing this object:
public virtual TResult Until<TResult>(Func<T, TResult> condition, CancellationToken token)
{
if (condition == null)
{
throw new ArgumentNullException("condition", "condition cannot be null");
}
var resultType = typeof(TResult);
if ((resultType.IsValueType && resultType != typeof(bool)) || !typeof(object).IsAssignableFrom(resultType))
{
throw new ArgumentException("Can only wait on an object or boolean response, tried to use type: " + resultType.ToString(), "condition");
}
Exception lastException = null;
var endTime = this.clock.LaterBy(this.timeout);
while (true)
{
token.ThrowIfCancellationRequested();
try
{
var result = condition(this.input);
if (resultType == typeof(bool))
{
var boolResult = result as bool?;
if (boolResult.HasValue && boolResult.Value)
{
return result;
}
}
else
{
if (result != null)
{
return result;
}
}
}
catch (Exception ex)
{
if (!this.IsIgnoredException(ex))
{
throw;
}
lastException = ex;
}
// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!this.clock.IsNowBefore(endTime))
{
string timeoutMessage = string.Format(CultureInfo.InvariantCulture, "Timed out after {0} seconds", this.timeout.TotalSeconds);
if (!string.IsNullOrEmpty(this.message))
{
timeoutMessage += ": " + this.message;
}
this.ThrowTimeoutException(timeoutMessage, lastException);
}
Thread.Sleep(this.sleepInterval);
}
}
I will mark the previous answer as correct, just putting here for a more detailed and added authoritative source also.
Until yesterday it was working and I didn't even touch the code but this error popped up and since that it just says this:
Reference to type 'IAsyncEnumerable<>' claims it is defined in
'System.Interactive.Async', but it could not be found.
I did a discord bot and I want to delete messages with it
[Command("clear")]
public async Task Clear(string StringNum = null)
{
try
{
if (!Context.Guild.CurrentUser.GuildPermissions.ManageMessages)
{
await ReplyAsync("Sorry, I don't have permission for this!");
}
else
{
var user = Context.User as SocketGuildUser;
if (user.GuildPermissions.ManageMessages)
{
int IntNum = 1;
bool intparse = int.TryParse(StringNum, out int n);
if (intparse)
{
IntNum = int.Parse(StringNum);
}
var messages = await Context.Channel.GetMessagesAsync(IntNum + 1).Flatten();
await (Context.Channel as SocketTextChannel).DeleteMessagesAsync(messages);
}
else
{
await ReplyAsync("You don't have permission for this command!");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.GetBaseException());
}
}
The error is at the line where I try to get the messages
I ran in to this. I had to install System.Interactive.Async 3.1.1 rather than 4.0.0. So I assume it is no longer in 4.0.0.
URL: http://bcmprod.brill.com/rsuite-cms/
I am trying to automate downloading of manuscripts from the client site above. I am using selenium phantomjs in C#.
I have the user credentials. But the elements that make up the login form (e.g. username, password) are not existing in the page source, but are existing when you inspect those elements in the browser.
These are the xpaths I'm using to locate them from "Inspect element" (IDs are dynamically assigned that's why I didn't use them):
string xpathUsername = ".//input[#name='user']";
string xpathPassword = ".//input[#name='pass']";
string xpathBtnLogin = ".//button[#type='submit'][#aria-label='Log In']";
How can I successfully login when the source returned by the driver has no login elements thus cannot be found, but yet existing when I inspect them in the browser?
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
using OpenQA.Selenium.Support.UI;
using WebCrawler.Helper;
namespace WebCrawler.Webcodes
{
class RSuite : IWebcode
{
List<string> errors = new List<string>();
string xpathUsername = ".//input[#name='user']";
string xpathPassword = ".//input[#name='pass']";
string xpathBtnLogin = ".//button[#type='submit'][#aria-label='Log In']";
public RSuite()
{ }
public List<Record> GetRecords()
{
Console.WriteLine(string.Format("Crawling: {0}", Config.Url));
List<Record> recordList = new List<Record>();
try
{
PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
using (IWebDriver driver = new PhantomJSDriver(service))
{
driver.Navigate().GoToUrl(Config.Url);
Console.WriteLine("\nChecking elements availability ...");
// code exception here: I couldn't get all these elements
IWebElement username = Element("User ID", GetElement(driver, xpathUsername));
IWebElement password = Element("Password", GetElement(driver, xpathPassword));
IWebElement btnlogin = Element("Login Button", GetElement(driver, xpathBtnLogin));
// input credentials
Console.WriteLine("\nAttempting to login ...");
if (username != null && password != null && btnlogin != null)
{
username.Clear();
username.SendKeys(Config.Username);
password.Clear();
password.SendKeys(Config.Password);
// is button clicked & loaded a new page? (If true, login is successful)
if (IsPageLoaded(driver, btnlogin))
{
Console.WriteLine("Logged in successfully.");
// do some action
// download files
}
else
{ ErrorHandler("Login failed."); }
}
else
{ ErrorHandler("Login failed."); }
}
// release
service.Dispose();
}
catch (Exception err)
{ ErrorHandler(err.GetBaseException().ToString()); }
// generate report for caught errors, if any
if (errors.Count() > 0)
Config.ErrorReport(this.GetType().Name.Trim().ToUpper(), string.Join("\n\n", errors));
return recordList;
}
private IWebElement GetElement(IWebDriver driver, string xPath)
{
IWebElement element = null;
try
{
// wait for elements to load
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
Func<IWebDriver, IWebElement> waitForElement = new Func<IWebDriver, IWebElement>((IWebDriver d) =>
{
element = d.FindElement(By.XPath(xPath));
if (element != null)
{ return element; }
return null;
});
return wait.Until(waitForElement);
}
catch (Exception err)
{
ErrorHandler(err.GetBaseException().ToString());
return null;
}
}
private IWebElement Element(string label, IWebElement element)
{
if (element != null)
{ Console.WriteLine(string.Format("{0}: Yes", label)); }
else
{ Console.WriteLine(string.Format("{0}: No", label)); }
return element;
}
private bool IsPageLoaded(IWebDriver driver, IWebElement element)
{
try
{
// page redirected? Or is the element still attached to the DOM?
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
element.Click();
return wait.Until(ExpectedConditions.StalenessOf(element));
}
catch (Exception err)
{
ErrorHandler(err.GetBaseException().ToString());
return false;
}
}
private void ErrorHandler(string error)
{
Console.WriteLine(error);
errors.Add(error);
}
}
}
As per your question the url http://bcmprod.brill.com/rsuite-cms/ is based on Ember.js so you have to induce WebDriverWait inconjunction with ExpectedConditions method ElementToBeClickable() while you look out for the elements.
The Locator Strategies to identify the desired fileds are as follows:
User ID:
string username = "//input[#class='ember-view ember-text-field finput text-field component' and #name='user']";
Password:
string password = "//input[#class='ember-view ember-text-field finput text-field component' and #name='pass']";
Log In:
string loginbtn = "//label[#class='ui-button-text']";
The code below is not working. (no exceptions thrown). Totally clueless why is not changed When I check in the GUI, there is a new version, with no changes!
public static void SetEntityWebName(ProcessEntity entity, SPWeb entityWeb)
{
try
{
entityWeb.AllowUnsafeUpdates = true;
var welcomePageListItem = entityWeb.GetFile(entityWeb.RootFolder.WelcomePage).Item;
var welcomePage = entityWeb.GetFile(entityWeb.RootFolder.WelcomePage);
welcomePage.CheckOut();
if (entity.Type == Entity.Job)
{
entityWeb.Title = ((SyncJobs_Result)entity.Entity).JobName;
welcomePageListItem["Title"] = ((SyncJobs_Result)entity.Entity).JobName;
welcomePage.Update();
}
if (entity.Type == Entity.Client)
{
entityWeb.Title = ((SyncClients_Result)entity.Entity).ClientName;
welcomePageListItem["Title"] = ((SyncClients_Result)entity.Entity).ClientName;
welcomePage.Update();
}
if (entity.Type == Entity.Opportunity)
{
entityWeb.Title = ((SyncOpportunities_Result)entity.Entity).OpportunityName;
welcomePageListItem["Title"] = ((SyncOpportunities_Result)entity.Entity).OpportunityName;
welcomePage.Update();
}
welcomePage.CheckIn(string.Empty);
welcomePage.Publish(string.Empty);
entityWeb.Update();
}
catch (Exception ex)
{
}
}
I think you also have to update the welcomePageListItem list item .
I am not sure but , give it a try
public static string GetContentFromSPList(string cValueToFind)
{
string cValueFound = "";
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("http://mysite"))
{
site.AllowUnsafeUpdates = true;
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList oListAbout = web.Lists["About"];
SPQuery oQuery = new SPQuery();
oQuery.Query = "<OrderBy><FieldRef Name='myField' /></OrderBy><Where><Eq><FieldRef Name='myField' /><Value Type='Choice'>" + cValueToFind + "</Value></Eq></Where>";
SPListItemCollection collListItems = oListAbout.GetItems(oQuery);
foreach (SPListItem oListItem in collListItems)
{
cValueFound = (oListItem["FieldContents"] != null ? oListItem["FieldContents"].ToString() : "");
}
}
}
return cValueFound;
});
//return cValueFound;
}
catch (Exception ex)
{
}
finally
{
//return cValueFound;
}
}
Above is the piece of code.
Problem is not allowing to return the string. It keeps on giving compilation errors. I am sure I am doing something wrong!!.
Thanks.
I suppose it's something like:
"not all codes return value".
If so, just add
public static string GetContentFromSPList(string cValueToFind)
{
string cValueFound = "";
try
{
//code
}
catch (Exception ex)
{
}
finally
{
//some cleanup
}
return cValueFound ;
}
Put this at the bottom of your method because you don't return if an exception is caught.
catch (Exception ex)
{
return cValueFound;
}
finally
{
}
}
You cannot return from finally,
(control cannot leave the body from finally clause or something)
move the return either after finally or from catch
just add your return statement below finally block.
Dont return in try blck.
I have seen developers missing this lot of times. Reason this happens is because once you define the return type of a function, then function should have a return statement at all exit points. In this case a function should have a return statement one at the end of the try block and one inside a catch block or just one right at the bottom as Tigran has defined. If you do not intend to return any thing from the catch block then just return null;
public static string GetContentFromSPList(string cValueToFind)
{
string value= "";
try
{
//code
return value;
}
catch (Exception ex)
{
return null;
}
finally
{
//some cleanup
}
}