Ignore screen reader text in serenity - selenium

serenity is returning the screen reader text along with the visible text in the screen. How to get text which is visible to the user?
public static Target TransactionTypeOption = Target.the("Transaction Type options").located(By.xpath("//ipb-dropdown[#class='type-dropdown ']//li//div"));
List<String> options = Text.of(TransactionTypeOption).viewedBy(actor).asList();
I have used bootstrap Sr-only class for the screen reader text.
So, I just wanted to read the first content which is "All Transactions" but serenity is returning me "All Transactions white spaces , current selection"

The XPath you are using is selecting the div, which also picks up some text under the div, which is , current selection in this case. I've seen this issue before with Selenium, and the only solution is to handle the extra text in your code.
public static Target TransactionTypeOption = Target.the("Transaction Type options").located(By.xpath("//ipb-dropdown[#class='type-dropdown ']//li//div"));
string textToFilterOut = driver.findElement(By.xpath("//span[#class='sr-only']")).getText();
List<String> options = Text.of(TransactionTypeOption).replace(textToFilterOut, "").viewedBy(actor).asList();

Related

Text Field with Standard PsiElement Auto Completion in IntelliJ Plugin

I'm trying to create a simple text field with auto completion for my IntelliJ plugin. I think this should be pretty simple but so far I've run into dead ends...
E.g. this should work as far as I understand:
EditorTextField format = new TextFieldWithCompletion(currentEditor.getProject(),
provider,
"",
true,
true,
true);
The problem is the provider. I'd expect to see a provider that isn't a list provider. I just want to show the completion matching the current line in the editor cursor so I'd like the full completion dialog and not just a short list of options.
I also looked at TextFieldWithAutoCompletion but it seems to be designed for hardcoded string values instead of free form completion.
I just want the standard Java/Kotlin completion. Not a custom list or anything like that. I saw some discussion with replacing the document of the text field but I couldn't get that to work either. I have a PsiExpressionCodeFragment and would expect there to be a completion provider that accepts that but I can't find it.
For reference what I want to do is something very similar to the conditional statement in the breakpoint dialog.
Another approach illustrated here is:
JavaCodeFragmentFactory jcff = JavaCodeFragmentFactory.getInstance(currentEditor.getProject());
PsiFile pf = PsiDocumentManager.getInstance(currentEditor.getProject()).getPsiFile(currentEditor.getDocument());
PsiElement psiElement = pf.findElementAt(currentEditor.getCaretModel().getOffset());
PsiExpressionCodeFragment fragment = jcff.createExpressionCodeFragment("", psiElement,null, false);
EditorTextField f = new EditorTextField(PsiDocumentManager.getInstance(currentEditor.getProject()).getDocument(fragment),
currentEditor.getProject(),
FileTypes.PLAIN_TEXT, false, true);
This loads the UI but doesn't popup code completion no matter what I type.
The trick is to create an editor that contains an instance of the Document. And this document refers to a language and a psi element context:
JPanel panel = new JPanel();
// Just detect an element under caret for context
PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument());
PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset());
PsiExpressionCodeFragment code = JavaCodeFragmentFactory.getInstance(editor.getProject()).createExpressionCodeFragment("", element, null, true);
Document document = PsiDocumentManager.getInstance(editor.getProject()).getDocument(code);
EditorTextField myInput = new EditorTextField(document, editor.getProject(), JavaFileType.INSTANCE);
myInput.setPreferredWidth(300);
panel.add(myInput);
return panel;
Here the caret used to be located on dsa5, so the dsa5 variable is not yet visible for the completion.

PdfFormField simply does not hide when setting the visibility to HIDDEN

I'm setting the visibility of a PdfFormField to HIDDEN using the setVisibility() method with parameter PdfFormField.HIDDEN. Still, on flattening it, the field does not hide. Below is the code to do so.
File file = new File("path to PDF file");
baos = new ByteArrayOutputStream();
pdfDoc = new PdfDocument(new PdfReader(file.getAbsolutePath()), new PdfWriter("path to flattened PDF file"));
//This function removes all the permissions.
removePdfPermissions();
form = PdfAcroForm.getAcroForm(pdfDoc, true);
fields = form.getFormFields();
fields.get("HumanSubjectsText").setVisibility(PdfFormField.HIDDEN);
fields.get("HumanSubjects").setVisibility(PdfFormField.HIDDEN);
form.flattenFields();
pdfDoc.close();
Setting the values of the fields to empty string "" is a workaround, but not the proper way.
The fields "HumanSubjects" and "HumanSubjectsText" correspond to a checkbox and its correspond text on page 2. (Human Subjects)
Link to PDF file
The fields could not be hidden using iText library. In contrast to Bruno's comment, one of the methods from iText library worked well, the setValue(). I'm not quite sure why the setVisibility() fails.
However, I was able to hide the field using Master PDF editor tool. I've attached a screenshot of this tool, where you can change the visibility for a form field from the General tab.
An observation: In the com.itextpdf.forms.fields.PdfFormField some of the constants defined are as follows:
public static final int HIDDEN = 1;
public static final int VISIBLE_BUT_DOES_NOT_PRINT = 2;
public static final int HIDDEN_BUT_PRINTABLE = 3;
public static final int VISIBLE = 4;
The Master PDF editor also has similar options to hide a field. Please refer to the attached screenshot.
NOTE: My requirement was just to simply hide the field. It could be achieved programmatically by using a library like iText or with some PDF editor tool.

How do you automate DevExpress Combo Boxes with Selenuim/Watir?

DevExpress builds combo boxes in a very odd way. The standard identification built in to Selenuim and Watir (including Page Objects) does not see it as a Select List.
So how can you automate these successfully?
So as it turns out, DevExpress builds combo boxes as a text box with several layered tables associated with it but not under the text box in the HTML tree.
interactions are all done via embedded scripts.
I found the simplest way to automate this object is to identify the text box and the lowest table containing the list of items (3rd table down).
for example (using Watir and Page Objects)
table(:list,:id => 'ComboBoxValue_DDD_L_LBT')
text_field(:state, :id => 'ComboBoxValue_I') #:name => 'State')
I have not found a way to get better IDs at these levels, but we are working that issue.
Then your select code looks like this:
self.state_element.click
row = list_element.find { |row| row[0].text == value }
row.click
Note that with Selenium, you can execute arbitrary javascript in the client to query and set the control's state (if the client-side is enabled for the control). Here's how I did so to extract (and set) the selected text from a combobox named localeSelectList:
// unit test code, c#
[TestMethod]
public void SomeTestMethod()
{
IWebDriver ff = new FirefoxDriver();
ff.Navigate().GoToUrl(homeUrl);
// find the element as an iWebElement
IWebElement localeBox = ff.FindElement(By.CssSelector("#localeSelectList"));
Assert.IsTrue(localeBox.Enabled);
// get the text from the control via javascript
var locale = Util.GetControlText(ff, localeSelectList);
Assert.IsTrue(locale == "English");
// set the text in the control via javascript
Util.SetControlText(ff, localeSelectList, "German");
// verify the text was set
locale = Util.GetControlText(ff, localeSelectList);
Assert.IsTrue(locale == "German");
}
// helper methods, Util class
static public string GetControlText(IWebDriver driver, string controlName)
{
string script = string.Format("return {0}.GetText();", controlName);
var controlText = ((IJavaScriptExecutor)driver).ExecuteScript(script);
return controlText.ToString();
}
static public void SetControlText(IWebDriver driver, string controlName, string controlText)
{
string script = string.Format("{0}.SetValue('{1}');", controlName, controlText);
((IJavaScriptExecutor)driver).ExecuteScript(script);
}
It's not quite the same thing as interacting with the extensions via primitives (clicks, keystrokes, etc) as it won't fire the event handlers for these events, but if your extension uses 'valueChanged' events instead of primitive handlers it's pretty close to the same.
Also note: you can use client-side javascript to find and return elements using jquery/css selectors and ids, as follows:
IWebElement element = (IWebElement) ((IJavaScriptExecutor)driver).ExecuteScript("return $('#.myElementId');")
That's right with several layered tables, but I would like to add that they are only visible when combobox is clicked. First
var cmbParameterGruppen = webDriver.FindElement(By.Id("phContent_ParameterGruppenComboBox_I"));
cmbParameterGruppen.Click();
and then
var tblItems = webDriver.FindElement(By.Id("phContent_ParameterGruppenComboBox_DDD_L_LBT"));
var parameterGruppen = tblItems.FindElements(By.XPath(".//*"));
var count = parameterGruppen.Count;
Debug.WriteLine($"Count = {count}");
if(count > 0)
parameterGruppen[count - 1].Click();
I select hier last row.

InDesign CS6 scripting - Add overflowing content on next page(s)

After I imported XML-Data into an InDesign document I see that red plus symbol at the textframe at the end of the first page.
How can I insert/move that content on next page(s) with scripting?
This script should do what you want. :)
var myDoc = app.activeDocument;
var myFrames = myDoc.textFrames;
while (myFrames[0].overflows === true) {
var myNewPage = myDoc.pages.add();
var myMargin = myNewPage.marginPreferences;
var myBounds = [myMargin.top, myMargin.left, myDoc.documentPreferences.pageHeight - myMargin.bottom, myDoc.documentPreferences.pageWidth - myMargin.right];
var myOldRuler = myDoc.viewPreferences.rulerOrigin;
myDoc.viewPreferences.rulerOrigin = RulerOrigin.pageOrigin;
with(myDoc.pages[-1].textFrames.add()) {
geometricBounds = myBounds;
previousTextFrame = myDoc.pages[-2].textFrames[0];
}
myDoc.viewPreferences.rulerOrigin = myOldRuler;
}
The TextFrame object has a property overflows: Bool, readonly. If true, the story has overset text.
The TextFrame object has also a property nextTextFrame: r/w The next text frame in the thread. Can return: TextFrame or TextPath. Can also accept: NothingEnum enumerator.
http://jongware.mit.edu/idcs6js/pc_TextFrame.html
not sure you need scripting... if the document is set up as a template simply click the plus sign and "capture" the contents. then move to the next page and click where you want the text to reflow to. adjust the text boxes as needed to suit.
For the non-scripting solution to flowing overset text frames, after adding a new page, hold down shift before clicking. This will cause the text to autoflow on as many pages as it takes until there is no longer an overset text frame.
From CS4, we can enable the "Smart Text Reflow" to automatically flow text to the available content. It will insert the pages automatically.
Edit Menu \ Preferences \ Type \ Smart Text Reflow
Also, it comes with "Delete Empty Pages", so when the content goes less, then it will automatically remove the empty pages accordingly.

attach image to fdf using itextsharp

I'm working to refactor a PDF form web application that is using the Active PDF Toolkit and the FDFToolkit from Adobe. My goal is to use iTextSharp to:
Pre-populate the form fields with data from the database
Allow the user to attach a signature and/or barcode image via FDF
Item #1 is not the problem. Item #2 is the biggest challenge. Let me provide some background:
This is a web application which renders the PDF form once. After the initial load, there are 2 key buttons on the form which submit the PDF form to a URL with an action parameter in the query string. These buttons are called "Save" and "Sign". The Save button takes the FDF field dictionary and saves it to the database. The Sign button looks up the signature for the logged-in user and attaches the signature image to the FDF and writes the FDF to the HTTP Response.
The FDFToolkit supports attaching an image to a field using this method:
FDFSetAP(string bstrFieldName, short whichFace, string bstrFileName, short pageNum)
iTextSharp does not offer a comparable method in the FdfWriter class. I've considered subclassing the FdfWriter class and adding my own method to attach an image, but wanted to reach out here to see if anyone has had the same problem.
I have been able to overlay an image on top of a field using this method, but this is in the underlying PDF and not the FDF.
AcroFields.FieldPosition pos = _Stamper.AcroFields.GetFieldPositions("SIGNATUREFIELD").First();
Image signature = Image.GetInstance("Signature.gif");
image.SetAbsolutePosition(pos.position.Left, pos.position.Bottom);
image.ScaleToFit(pos.position.Width, pos.position.Height);
PdfContentByte pcb = _Stamper.GetOverContent(pos.page);
pcb.AddImage(image);
Thanks!
I've put images on forms by using the PdfStamper and making Pushbutton fields. You can replace your existing field with a Pushbutton field and set the Pushbutton to READ_ONLY so that it can't be pressed and it will look like a static image. This will keep the image you're trying to add as a field annotation instead of adding it to the page content.
using (PdfStamper stamper = new PdfStamper(new PdfReader(inputFile), File.Create(outputFile)))
{
AcroFields.FieldPosition fieldPosition = stamper.AcroFields.GetFieldPositions(fieldName)[0];
PushbuttonField imageField = new PushbuttonField(stamper.Writer, fieldPosition.position, fieldName);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.Image = iTextSharp.text.Image.GetInstance(imageFile);
imageField.ScaleIcon = PushbuttonField.SCALE_ICON_ALWAYS;
imageField.ProportionalIcon = false;
imageField.Options = BaseField.READ_ONLY;
stamper.AcroFields.RemoveField(fieldName);
stamper.AddAnnotation(imageField.Field, fieldPosition.page);
}