The program for ordering statements on the registry, I can not go to their pop-up window, selenium does not see that any new is being created.
Is it possible to do it through Xpath without using the transition to the Popup window, a browser function, or in another way in Selenium (Chrome)?
New window detection function:
public static string ClickAndSwitchWindow(IWebElement elementToBeClicked,
IWebDriver driver, int timer = 2000)
{
System.Collections.Generic.List<string> previousHandles = new
System.Collections.Generic.List<string>();
System.Collections.Generic.List<string> currentHandles = new
System.Collections.Generic.List<string>();
previousHandles.AddRange(driver.WindowHandles);
elementToBeClicked.Click();
Thread.Sleep(timer);
for (int i = 0; i < 20; i++)
{
currentHandles.Clear();
currentHandles.AddRange(driver.WindowHandles);
foreach (string s in previousHandles)
{
currentHandles.RemoveAll(p => p == s);
}
if (currentHandles.Count == 1)
{
driver.SwitchTo().Window(currentHandles[0]);
Thread.Sleep(100);
return currentHandles[0];
}
else
{
Thread.Sleep(500);
}
}
return null;
}
The piece of code itself:
//After this click of this element, a window opens:
//"Send request"
IWebElement PopWindowsstart = ww.Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body/div[1]/div[6]/div[4]/div/div/section/div[2]/div[2]/div/div/div[2]/div/div[2]/div/div/div/div[1]/div/div/div/div[1]/div/div/div/div[4]/div/div/div/div[1]/div/div/div/div[1]/div/div/span/span")));
//Search for a new window
string newWin = ClickAndSwitchWindow(PopWindowsstart, Browser, 2500);
PopupWindowFinder finder = new PopupWindowFinder(Browser);
//Switch to a new window
Browser.SwitchTo().Window(newWin);
//Statement Number:
IWebElement NumExctract = ww.Until(ExpectedConditions.ElementIsVisible(By.XPath("div[class='v-label v-label-tipFont tipFont v-label-undef-w'] b")));
//Read check
MessageBox.Show(NumExctract.Text);
//"Continue work"
ww.Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body/div[7]/div/div/div/div[3]/div/div/div/div[1]/div/div/div/div[2]/div/div/div/div[1]/div/div/div/div[1]/div/div/span/span"))).Click();
//"Change"
ww.Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body/div[1]/div[6]/div[4]/div/div/section/div[2]/div[2]/div/div/div[2]/div/div[2]/div/div/div/div[1]/div/div/div/div[2]/div/div/div/div[1]/div/div/div/div[2]/div/div/span/span"))).Click();
Thread.Sleep(300000);
Type window:
Let's make this a bit easier.
If you need to switch to a popup, try the below.
public static string SwitchToPopup()
{
var mainHandle = Driver.CurrentWindowHandle;
var handles = Driver.WindowHandles;
foreach (var handle in handles)
{
if (mainHandle == handle)
{
continue;
}
Driver.SwitchTo().Window(handle);
break;
}
var result = Url;
return result;
}
When you need to switch back, use:
public static void GoToMainHandle()
{
var handles = Driver.WindowHandles;
foreach (var handle in handles)
{
Driver.SwitchTo().Window(handle);
break;
}
}
That being said, your xpath is not something that should ever be used. Please look at https://www.w3schools.com/xml/xpath_intro.asp and rewrite it. When you use chrome to give you your xpath like:
ww.Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body/div[1]/div[6]/div[4]/div/div/section/div[2]/div[2]/div/div/div[2]/div/div[2]/div/div/div/div[1]/div/div/div/div[2]/div/div/div/div[1]/div/div/div/div[2]/div/div/span/span"))).Click();
If your dev adds a div in here somewhere, all of your tests will now fail. If your devs are not providing unique identifiers, work with them to resolve that. You should have id's, class names etc.
Try:
public static void PopUp()
{
_webDriver.SwitchTo().Alert().Accept();
}
Related
I want to make an auto injection scanner in any given website and I have to use c#.
I tried some things that I found online and none of them worked for me, until i find selenium but i keep getting this error message: "OpenQA.Selenium.ElementNotInteractableException: 'element not interactable", and I have no idea why.
I didn't find anything helpful online and I think the problem may be with selenium.
I tried to find SQL, JS and BASH injections, but the script fails when i try to interact with an input. I am using OWASP juice shop to test my code.
This is my code:
static int _crntTypeOfInjection;
const int ESQL = 0, EJS = 1, EBASH = 2;
static public bool IsImportantInput(string type)
{
bool valid = false;
string[] importantTypes = new string[] { "text", "email", "password", "search", "url" };
foreach (string check in importantTypes)
{
if (type == check)
{
return true;
}
}
return false;
}
public static string getCrntInjection()
{
switch (_crntTypeOfInjection)
{
case ESQL:
return "\' OR 1=1;--";
break;
case EBASH:
return "; echo Test";
break;
case EJS:
return "<img src=\"http:\\\\url.to.file.which\\not.exist\" onerror=alert(\"JS injection success\");>";
break;
}
return "defult";
}
static public bool AttackSuccessful(string normalPage, string InjectedPage, string MainUrl, string afterClickUrl)
{
if (afterClickUrl != MainUrl || InjectedPage.Contains("Internal Server Error") || InjectedPage.Contains("JS injection success") || InjectedPage.Contains("Test"))
{
return true;
}
return false;
}
static public void Injection(string url)
{
string InjectedPage = "", NormalPage = "", AfterClickUrl = "";
var driver = new ChromeDriver("C:\\Users\\nirya\\");
driver.Url = url;
Console.WriteLine(driver.PageSource);
Actions a = new Actions(driver);
foreach (var button in driver.FindElements(By.CssSelector("button")))
{
// INJECTED PAGE
a.MoveByOffset(0, 0).Click().Perform();
foreach (IWebElement input in driver.FindElements(By.TagName("input")))
{
Console.WriteLine(input.Text);
Console.WriteLine(input.TagName);
try
{
if (IsImportantInput(input.GetAttribute("type")))
{
input.Click(); // *** HERE IS THE PROBLEM ***
input.Clear();
input.SendKeys(getCrntInjection());
}
}
catch (NoSuchElementException)
{
continue;
}
}
button.Click();
InjectedPage = driver.PageSource;
AfterClickUrl = driver.Url;
driver.Navigate().Back();
// NORMAL PAGE
a.MoveByOffset(0, 0).Click().Perform();
foreach (IWebElement input in driver.FindElements(By.CssSelector("input")))
{
try
{
if (IsImportantInput(input.GetAttribute("type")))
{
input.Clear();
input.SendKeys("normal");
}
}
catch (NoSuchElementException)
{
continue;
}
}
button.Click();
NormalPage = driver.PageSource;
driver.Navigate().Back();
if (AttackSuccessful(NormalPage, InjectedPage, url, AfterClickUrl))
{
// add to database
}
}
}
static void Main(string[] args)
{
Injection("http://localhost:3000/#/login");
}
Is there a problem with my code? Or is there another library that i can use instead?
Here is the code for my work.
public void InsertValue(WordprocessingDocument doc, string bookMark, string txt)
{
try
{
RemoveBookMarkContent(doc, bookMark);
var bmStart = FindBookMarkStart(doc, bookMark);
if (bmStart == null)
return;
var run = new Run();
run.Append(GetRunProperties());
run.Append(new Text(txt));
bmStart.Parent.InsertAfter(run, bmStart);
}
catch (Exception c)
{
//not Exception
}
}
private void RemoveBookMarkContent(WordprocessingDocument doc, string bmName)
{
BookmarkStart bmStart = FindBookMarkStart(doc, bmName);
if (bmStart == null)
return;
BookmarkEnd bmEnd = FindBookMarkEnd(doc, bmStart.Id);
while (true)
{
var run = bmStart.NextSibling();
if (run == null)
{
break;
}
if (run is BookmarkEnd && (BookmarkEnd)run == bmEnd)
{
break;
}
run.Remove();
}
}
There are still several auxiliary classes not written.Work process, first find the bookmark location, delete the content of the bookmark location, and then add it.I've also tried to add one Paragraph to the bookmark location.But that doesn't work.
Document to insert in bookmark eg:露点:U=0.15℃(k=2);相对湿度:U=1.0%RH(k=2).Both u and K must be italics.Any help will be appreciated.Thanks.
I tried a new component.[Spire.Office.][1]
At the beginning, I didn't think of a solution, but I used the global search and replacement to determine whether the search location has bookmarks, which perfectly solved the problem.
Here is the code for my work.
var selection = document.FindAllString("U", false, true);
foreach (var sec in selection)
{
var t = sec.GetAsOneRange();
if (sec.GetAsOneRange()?.Owner?.LastChild?.DocumentObjectType == DocumentObjectType.BookmarkEnd)
{
sec.GetAsOneRange().CharacterFormat.Italic = true;
}
}
I didn't try to do this with openxml, but I think the principle should be consistent.
[1]: https://www.e-iceblue.cn/Buy/Spire-PDF-NET.html
I am trying to scrape alle pages of http://www.menorcarentals.com/en/villas but i am having some problems, as it give me the first page every time.
My approach is the find all inputs and selects on the page, and the set the value of __EVENTTARGET to the value of the button i want to click, which have worked before, but this site just won't budge.
Method to get all Input Fields
public static Dictionary<string, string> GetInputFields(CQ dom)
{
Dictionary<string, string> result = new Dictionary<string, string>();
foreach (var v in dom.Find("input"))
{
var value = v.Cq().Attr("value");
var key = v.Cq().Attr("name");
if (!string.IsNullOrWhiteSpace(value))
{
if (!result.ContainsKey(key))
{
result.Add(key, value);
}
else
{
result[key] = value;
}
}
}
// Get all selects
foreach (var s in dom.Select("select"))
{
var select = s.Cq();
var key = select.Attr("name");
foreach (var option in select.Children("option"))
{
var opt = option.Cq();
if(!string.IsNullOrWhiteSpace(opt.Attr("selected")))
{
if (!result.ContainsKey(key))
{
result.Add(key, opt.Val());
}
else
{
result[key] = opt.Val();
}
}
}
}
return result;
}
My code to run though the different pages
string searchPageUrl = "http://www.menorcarentals.com/en/villas";
var html = DownloadHelper.Download(searchPageUrl);
while (true)
{
CQ dom = html;
// parse page and get info i need here
// Find the next page
var pagination = dom.Select("#ctl00_Content_dpVillas").Children();
bool foundCurrent = false;
string clickElementName = string.Empty;
foreach (var pagi in pagination)
{
if (pagi.Classes.Any(x=>x.ToLower() == "current"))
{
foundCurrent = true;
}
else if (foundCurrent)
{
var href = pagi.Cq().Attr("href");
clickElementName = RegexHelper.Match(#"doPostBack\(\'([^']+)", href);
break;
}
}
if (string.IsNullOrWhiteSpace(clickElementName))
{
break; // no more pages
}
var inputFields = ScraperHelper.GetInputFields(html);
// Simulate that we click the next button
if (!inputFields.ContainsKey("__EVENTTARGET"))
inputFields.Add("__EVENTTARGET", String.Empty);
inputFields["__EVENTTARGET"] = clickElementName;
html = DownloadHelper.Post(searchPageUrl, inputFields);
}
Turn off your JavaScript along with cookies in browser (delete cookies before turning off) and than see the actual page that CsQuery will use.
This might be the result of why you can't parse anything,
For example an actual content of the page loads with AJAX.
I'm not a developer so maybe the answer is out there for a different solution but I can't really translate it from python or something else.
I'm trying to use the AWS .NET SDK to find an instance and then get the instance's tags. I've gotten as far as being able to determine if an instance is up and running or not. I also see how I can create and delete tags (not in code example below). But I don't see an easy way to actually check if a tag exists and get the value of the tag if it does exist.
Sorry if I'm missing the obvious but this is all new to me. Here's an example of the code I'm using to check if an instance is running.
instanceID = "i-myInstanceID";
do {
var myrequest = new DescribeInstanceStatusRequest();
DescribeInstanceStatusResponse myresponse = ec2.DescribeInstanceStatus(myrequest);
int isCount = myresponse.DescribeInstanceStatusResult.InstanceStatuses.Count;
for (int isc=0; isc < isCount; isc++) {
InstanceStatus instanceStatus = myresponse.DescribeInstanceStatusResult.InstanceStatuses[isc];
if (instanceStatus.InstanceId.Contains(instanceID)) {
Console.WriteLine("It looks like instance "+instanceID+" is running.");
idIdx = isc;
foundID = true;
break;
}
}
if ((foundID==false) && (secondCounter==1)) {
Console.Write("Looking for instance "+instanceID);
} else {
Console.Write(".");
}
Thread.Sleep(1000);
secondCounter++;
if (secondCounter > 5) {
break;
}
} while (foundID == false) ;
First send a DescribeInstancesRequest to get the list of Instances:
public DescribeInstancesResult GetInstances(Ec2Key ec2Key)
{
_logger.Debug("GetInstances Start.");
AmazonEC2 ec2 = CreateAmazonEc2Client(ec2Key);
var ec2Request = new DescribeInstancesRequest();
DescribeInstancesResponse describeInstancesResponse = ec2.DescribeInstances(ec2Request);
DescribeInstancesResult result = describeInstancesResponse.DescribeInstancesResult;
_logger.Debug("GetInstances End.");
return result;
}
Then loop through the instances until you find the one you want, and then use the Tag.GetTagValueByKey method:
// This just calls the above code
DescribeInstancesResult ec2Instances = _ec2ResourceAccess.GetInstances(ec2Key);
var returnInstances = new List<Ec2UtilityInstance>();
foreach (var reservation in ec2Instances.Reservation)
{
foreach (var runningInstance in reservation.RunningInstance)
{
var returnInstance = new Ec2UtilityInstance();
returnInstance.InstanceId = runningInstance.InstanceId;
returnInstance.InstanceName = runningInstance.Tag.GetTagValueByKey("Name");
returnInstance.Status = (Ec2UtilityInstanceStatus)Enum.Parse(typeof(Ec2UtilityInstanceStatus), runningInstance.InstanceState.Name, true);
returnInstance.DefaultIp = runningInstance.Tag.GetTagValueByKey("DefaultIp");
returnInstance.InstanceType = runningInstance.InstanceType;
returnInstance.ImageId = runningInstance.ImageId;
returnInstances.Add(returnInstance);
}
}
Here is the link for full source that this was taken from:
https://github.com/escherrer/EC2Utilities
Common\Manager
and
Common\ResourceAccess
I have been searching for a solution for this, but to no avail. I have a button I'm clicking, that is sometimes taking a long while to return data, and the driver is timing out and just killing the app I guess.
I am trying to use the WebDriverWait class to accomplish this, but the Click() method is not available in the way I'm using it.
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));
bool clicked = wait.Until<bool>((elem) =>
{
elem.Click(); //Doesn't Work
return true;
});
The ImplicitlyWait() method is only for waiting for elements to load, but this times out on Click(), so it can't even look for an element.
The SetScriptTimeout() method just works with executing javascript, which I'm not doing.
Does anyone know of a way to do this?
try this :
WebDriverWait wait = new WebDriverWait(driver , 1000) ;
wait.until(ExcepctedConditions.elementToBeClickable(ById("element"));
Element can be ID of any element present on the next page you are redirected to .
Once Page loads fully then it will start executing your code .
Instead of Click you could try to use SendKeys. Unlike Click, SendKeys does not wait for the page to finish loading before resuming code execution. So you can do something like this:
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));
elem.SendKeys(Keys.Enter);
wait.Until<bool>((_driver) =>
{
//Check here if results have loaded yet
return true;
});
As a side note, I'm pretty sure Until takes in a IWebBrowser as an input, not an element, which is why you can't click on elem.
In addition to prestomanifesto's solution I can offer a less than ideal solution to that I implemented to solve this issue. It turns out it is throwing an exception - No Response etc... - so I just surrounded it in a try catch then waited for the popup to close, which seems to work fine.
You can substitute whatever you want in your loop, just make sure to put a counter in so it won't loop forever.
try
{
element.Click();
}
catch
{
cnt++;
do
{
//wait for whatever
cnt++;
Thread.Sleep(1000);
// Wait for 30 seconds for popup to close
} while (!string.IsNullOrEmpty(browser.CurrentWindowHandle) && cnt < 30);
}
I use this script :
private static void waitUntilScriptFoundAndExecute(String script) {
int tries = 0;
boolean found = false;
do {
tries++;
try {
driver.executeScript(script);
found = true;
} catch (NoSuchElementException nse) {
System.out.println("Wait for script NSE (" + tries + ")");
} catch (WebDriverException wde) {
System.out.println("Wait for script WDE (" + tries + ")");
} catch (Exception e) {
System.out.println("Wait for script E (" + tries + ")");
}
// Waiting
if (!found) {
System.out.println("Wait for script Not found (" + tries + ")");
waiting(SCRIPT_WAITING_INTERVAL);
}
} while (!found && tries < MAX_SCRIPT_WAIT_TRIES);
if (!found) {
System.out.println("Script aborted: " + script);
}
}
RepeatUntil Extension Method using LINQ Lambda expressions
Copy this code to your project:
public static class SeleniumExtensionMethods
{
public static IWebElement RepeatUntil<T>(this T obj,
Func<T, IEnumerable<IWebElement>> func,
Func<IWebElement, bool> compare,
int MaxRetry = 20)
{
//call function to get elements
var eles = func(obj);
IWebElement element = null;
while (element == null && MaxRetry > 0)
{
MaxRetry-=1;
//call the iterator
element = IterateCollection(compare, eles);
if (element == null)
{
Thread.Sleep(500);
//get new collection of elements
eles = func(obj);
}
};
return element;
}
private static IWebElement IterateCollection(
Func<IWebElement, bool> compare,
IEnumerable<IWebElement> eles){
IWebElement element = null;
eles.ToList().ForEach(
ele =>
{
//call the comparator
var found = compare(ele);
if (found) element = ele;
});
return element;
}
}
Call it using this syntax:
// You can change PageObjectType to IWebDriver or IWebElement so that
// cb is of any type.
var element = cb.RepeatUntil<MyPageObjectType>(
//This is the first function to provide the elements
p => p.FindElements(By.ClassName("TreeNode")),
//This is the comparator
ele => ele.Text == nodeText && ele.Location.Y>YLocation);
Note: In the example above we are passing in a PageObjectType but you could change this to be of type IWebDriver or event IWebElement. All the type parameter does it allow you to use this as an extension method for the type you specify.
Note the flexibility of the extension method in that the caller can determine the collection as well as the comparator.
don't use thread sleep
public class(IWebDriver driver)
{
this.driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMinutes(1);
wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromMinutes(1));
}
public void class1()
{
wait.Until(ExpectedConditions.ElementToBeClickable(elem)).Click();
}