J'ai donc ce formulaire c # en utilisant les Webdriers Firefox Selenium.
En gros, j'ai besoin de vérifier si un élément existe et s'il ne clique pas sur un élément différent. S'il y a une vidéo et qu'elle est visionnée, elle devient W_VIEWED
Voici ce que j'ai eu jusqu'à présent
driver.FindElement(By.XPath("//div[@class='video']/a")).Click();
else {
driver.FindElement(By.XPath("//div[@class='W_VIEWED']/a")).Click();
}
Erreur 3 Seules les expressions d'affectation, d'appel, d'incrémentation, de décrémentation, d'attente et de nouvel objet peuvent être utilisées comme instruction. 242
Un nouveau type de sélénium. Merci pour l'aide.
Vous pouvez vérifier la sortie des éléments ou ne pas utiliser
bool isElementDisplayed = driver.findElement(By.xpath("element")).isDisplayed()
Rappelez-vous, findElement
throws exception s'il ne trouve pas élément, vous devez donc le gérer correctement.
Dans une de mes applications, j'ai traité l'exception en vérifiant l'élément dans une fonction distincte,
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Fonction d'appel,
if (IsElementPresent(By.Id("element name")))
{
//do if exists
}
else
{
//do if does not exists
}
Vous pouvez utiliser FindElements avec un "s" pour déterminer s'il existe, car FindElement génère une exception. Si FindElements ne renvoie pas d'élément, il renvoie une liste vide.
List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(driver.FindElements(By.XPath("//input[@att='something']")));
if(elementList.Count > 0)
{
//If the count is greater than 0 your element exists.
elementList[0].Click();
}
J'ai donc récemment trouvé une autre solution, beaucoup plus rapide. Si votre élément a un identifiant unique ou un attribut qui n'existe nulle part ailleurs sur la page, vous pouvez vérifier le PageSource.
driver.PageSource.Contains("UniqueID");
Il vérifie la page pour voir si l'ID ou un autre texte unique existe. Cela se produit presque instantanément, contrairement à l'utilisation d'une instruction Try/Catch, qui prend environ 20 secondes. FindElements prend également beaucoup de temps à exécuter.
C'est ce que j'utilise. la méthode "verify" retournera une valeur true ou false selon que l'élément existe. La méthode nommée "testfunc" est l'endroit où vous entrez le nom de l'élément. Dans cet exemple, je cherche à savoir si "anglais" est affiché sur la page . En outre, je remarque dans les commentaires ci-dessus que les gens disent qu'ils doivent attendre 10 secondes ou plus pour que la capture fonctionne. Essayez de supprimer l'attente explicite dans votre code pour que la capture fonctionne immédiatement.
static public bool verify(string elementName)
{
try
{
bool isElementDisplayed = driver.FindElement(By.XPath(elementName)).Displayed;
return true;
}
catch
{
return false;
}
return false;
}
static void testfunc()
{
bool test = verify("//option[contains(.,'English')]");
Console.WriteLine(test);
}
J'ai utilisé la solution de la réponse acceptée pendant un certain temps, mais j'avais besoin d'un moyen de vérification plus rapide, sans attendre le délai d'attente chaque fois qu'une vérification échouait. J'ai donc créé des fonctions d'extension fonctionnant sur IWebElement et IWebDriver qui vérifient l'existence d'un tag ou d'une classe. Veuillez pardonner les mises en forme incohérentes au début et à la fin du codeblock. L'éditeur de SO ne coopère pas; P
public static class ExtensionMethods {
public static bool ContainsTag(this IWebElement element, string tagName)
{
string elementText = element.GetAttribute("innerHTML");
return CheckStringForTag(elementText, tagName);
}
public static bool ContainsClass(this IWebElement element, string className)
{
string elementText = element.GetAttribute("innerHTML");
return CheckStringForClass(elementText, className);
}
public static bool ContainsTag(this IWebDriver driver, string tagName)
{
return CheckStringForTag(driver.PageSource, tagName);
}
public static bool ContainsClass(this IWebDriver driver, string className)
{
return CheckStringForClass(driver.PageSource, className);
}
private static bool CheckStringForTag(string text, string tagName)
{
if (!string.IsNullOrWhiteSpace(text))
{
return text.Contains("<" + tagName + ">") || text.Contains("</" + tagName + ">") || text.Contains("<" + tagName + " ");
}
return false;
}
private static bool CheckStringForClass(string text, string className)
{
if (!string.IsNullOrWhiteSpace(text))
{
string pattern = string.Format(".*class[\\s]?=[\\s]?.*[\\s'\"]{0}[\\s'\"].*.*", className);
Match m = Regex.Match(text, className, RegexOptions.IgnoreCase);
return m.Success;
}
return false;
}
public static string InnerHTML(this IWebElement element)
{
return element.GetAttribute("innerHTML");
}}
Note: Ceci est similaire à, mais développe la réponse de Dominic Giallombardo.
La réponse de Dominic Giallombardo a fonctionné pour moi. Sur les informations ajax qui se chargent sur l'arrière-plan, il est nécessaire d'attendre que l'élément apparaisse. Donc, si vous voulez attendre et agir lorsque l’élément apparaît, c’est possible avec lable et goto lable + else condition. Voici le code modifié qui attendra que l'élément apparaisse en boucle:
checksomeelement:
List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(driver.FindElements(By.XPath("//div[@class='video']/a")));
if (elementList.Count > 0)
{
elementList[0].Click();
}
else
{
System.Threading.Thread.Sleep(2000);
goto checksomeelement;
}
Cette méthode vous permettra d’attendre l’existence d’un élément. Ceci est particulièrement important dans les frameworks SPA front-end qui créent conditionnellement des éléments, comme VueJS. Vous pouvez modifier votre nombre de tentatives en fonction des performances de votre application. Dans tous les cas, votre ELEMENT_FIND_WAIT_TIME * ELEMENT_FIND_WAIT_RETRY_COUNT
millisecondes attendra avant d’échouer complètement. Cela a résolu le problème que nous avions.
protected Func<IWebElement> GetLazyElement(By by, int retryCount=0)
{
if (retryCount >= ELEMENT_FIND_WAIT_RETRY_COUNT)
{
throw new Exception("Wait timeout for element to show up" + by.ToString());
}
return new Func<IWebElement>(() => {
try
{
Debug.WriteLine("Finding element " + by.ToString());
var element = _webDriver.FindElement(by);
return element;
}
catch (Exception)
{
Debug.WriteLine($"Failed to find element: {by} (Waiting {ELEMENT_FIND_WAIT_TIME}ms)");
Thread.Sleep(ELEMENT_FIND_WAIT_TIME);
var lazyFunc = GetLazyElement(by, retryCount++);
return lazyFunc();
}
});
}