Issue
I have written a class in C# that opens a website and translates the inputted text. This class uses selenium which I use for the entire project.
I don't use an API because with the website I can translate all characters for free and with the API I've to pay for it. It's a small business so...
What's the problem: most of the time this class works perfectly fine, however when you set a long string as input I get an error message OpenQA.Selenium.WebDriverException: 'target frame detached (Session info: chrome=102.0.5005.63)
. This happens also when the internet connection is not stable enough (regular Wi-Fi for example). I can't figure out how to program it so that the program waits for the translation. Anyone a solution?
main code
public MainWindow()
{
InitializeComponent();
String[] franseZinnen = { "S’il vous plaît", "Je suis désolé", "Madame/Monsieur/Mademoiselle", "Excusez-moi", "Je ne comprends pas", "Je voudrais...", "Non, pas du tout", "Où sommes-nous?", "Pourriez-vous m’aider?", "Répétez s'il vous plaît.", "Où puis-je trouver un bon restaurant/café/la plage/le centre-ville?", "Je cherche cette adresse.", "J'ai besoin d'une chambre double..", "Je voudrais annuler ma réservation.", "Où est la boutique duty-free?", "Comment puis-je vous aider?", "Je cherche des chaussures.", "C’est combien?", "C’est trop cher!" };
List<String> uitkomsten = new List<string>();
String LangefranseTekst = "Temps ouais merde bière parce que du apéro. Vin vin croissant quelque manger. Quand même passer saucisson meilleur dans fromage quelque parce que.\r\nÀ la camembert boulangerie part omelette meilleur. Grève camembert fromage. Manger fois du coup carrément.\r\nEnée est juste le moyen de décorer l'oreiller de la vie. Duis eu tincidunt orci, de CNN. Tous mes besoins sont grands. Jusqu'à ce qu'il reçoive la messe et que l'urne flatte le laoreet. Proin reçoit beaucoup de rires. Suspendisse feugiat eros id risus vehicula lobortis. Vivamus ullamcorper orci a ligula pulvinar convallis.\r\nManger. Carrément guillotine saucisson épicé un apéro. Croissant boulangerie son du coup du coup moins quand même et paf le chien mais évidemment à révolution. À la du faire voila du coup. Évidemment entre et aussi voila.\r\nBaguette devoir camembert voila se disruptif disruptif et paf le chien se fais chier. Frenchtech se révolution monsieur du coup avec putain. Falloir disruptif grève comme même.\r\nVin omelette épicé. Comme même tout comme même. Peu camembert fromage parce que comme même voir ouais.\r\nDemander vin et aussi saucisson nous putain. De merde voila carrément et paf le chien il y a du coup aussi apéro.\r\nLe client est très important merci, le client sera suivi par le client. Énée n'a pas de justice, pas de résultat, pas de ligula, et la vallée veut la sauce. Morbi mais qui veut vendre une couche de contenu triste d'internet. Être ivre maintenant, mais ne pas être ivre maintenant, mon urne est d'une grande beauté, mais elle n'est pas aussi bien faite que dans un livre. Mécène dans la vallée de l'orc, dans l'élément même. Certaines des exigences faciles du budget, qu'il soit beaucoup de temps pour dignissim et. Je ne m'en fais pas chez moi, ça va être moche dans le vestibule. Mais aussi des protéines de Pour avant la fin de la semaine, qui connaît le poison, le résultat.";
/* // short translations
foreach (var item in franseZinnen)
{
ChromeDriver driver = new ChromeDriver();
String translation = vertalenNu.translateText(new ChromeDriver(), item, "fr", "en");
uitkomsten.Add(translation);
driver.Close();
}*/
// long translation
ChromeDriver driver = new ChromeDriver();
String translation = vertalenNu.translateText(new ChromeDriver(), LangefranseTekst, "fr", "en");
uitkomsten.Add(translation);
driver.Close();
String stringVoorBreakpoint = "";
}
code in class
[Serializable]
public class vertalenNu
{
public static String translateText(IWebDriver driver, String text, String languageSource, String languageDestination)
{
// nl - en - de - fr -es -it
driver.Url = "https://www.vertalen.nu/zinnen/";
driver.FindElement(By.Id("vertaaltxt")).SendKeys(text);
SelectElement testt = new SelectElement(driver.FindElement(By.Id("tselectfrom")));
testt.SelectByValue(languageSource);
SelectElement test = new SelectElement(driver.FindElement(By.Id("tselectto")));
test.SelectByValue(languageDestination);
driver.FindElement(By.XPath("//input[@title='Vertaal']")).Click();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
wait.Until(driver => driver.FindElement(By.ClassName("mt-translation-content")).Text != "");
IWebElement technicalSheet = driver.FindElement(By.ClassName("mt-translation-content"));
String technicalSheettext = technicalSheet.Text;
driver.Close();
driver.Quit();
return technicalSheettext;
}
}
Solution
You could try this solution:
First create a class that will handle translations
public interface ITranslator : IDisposable
{
void ClearInput();
string Translate(string text);
}
public class Translator : ITranslator
{
private const string Url = "https://www.vertalen.nu/zinnen/";
private const int Timeout = 20;
private By _source = By.Id("vertaaltxt");
private By _destination = By.Id("resulttxt");
private By _submit = By.XPath("//input[@type = 'submit']");
private readonly WebDriverWait _wait;
private readonly IWebDriver _driver;
public Translator()
{
_driver = new ChromeDriver();
_wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(Timeout));
_driver.Navigate().GoToUrl(Url);
}
public string Translate(string text)
{
_driver.FindElement(_source).SendKeys(text);
_driver.FindElement(_submit).Click();
_ = _wait.Until(d => d.FindElement(_destination).Text.Length > 0);
return _driver.FindElement(_destination).Text;
}
public void ClearInput()
{
_wait.Until(d => d.FindElement(_source)).Clear();
}
public void Dispose()
{
_driver.Dispose();
}
}
The next sample focuses on a WinForms solution but you can adjust it to whatever UI app you like:
public partial class MainWindow : Form
{
private readonly ITranslator _translator;
private const int MaxChars = 1500;
private int _currentCharsCount;
public MainWindow()
{
InitializeComponent();
_translator = new Translator();
}
private void translateBtn_Click(object sender, EventArgs e)
{
destinationTextBox.Text = _translator.Translate(sourceTextBox.Text);
_translator.ClearInput();
// or for better user experience use bellow code
// if you decide to use this code don't forget to mark async this method
//await Task.Run(() =>
//{
// destinationTextBox.Text = _translator.Translate(sourceTextBox.Text);
// _translator.ClearInput();
//});
}
private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
{
_translator.Dispose();
}
private void clickBtn_Click(object sender, EventArgs e)
{
sourceTextBox.Clear();
destinationTextBox.Clear();
charsCounter.Text = $"{MaxChars} characters remaining";
}
private void sourceTextBox_TextChanged(object sender, EventArgs e)
{
_currentCharsCount = MaxChars - sourceTextBox.TextLength;
charsCounter.Text = $"{_currentCharsCount} characters remaining";
}
}
Answered By - ggeorge
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.