Selecting a LI element from Dropdown - coded-ui-tests

I'm having problems with my data driven coded-ui test. I'm supposed to replace the info typed in the test with csv data.
I can succesfully replace login and password inputs with the csv data.. but I'm failing to replace a selected LI in the test with it's csv data.
I don't know how to select the LI since it seems to be a custom generated control element but I may be drifting.
The HTML looks like this:
<div id="cphCont_cphContAut_ddlTipoJur" class="ComboAzul" style="display:inline-block;">
<table id="cphCont_cphContAut_ddlTipoJur_ddlTipoJur_Table" class="ajax__combobox_inputcontainer" style="border-width:0px;border-style:None;border-collapse:collapse;display:inline-block;position:relative;top:5px;" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="ajax__combobox_textboxcontainer">
<input name="ctl00$ctl00$cphCont$cphContAut$ddlTipoJur$ddlTipoJur_TextBox" id="cphCont_cphContAut_ddlTipoJur_ddlTipoJur_TextBox" tabindex="3" autocomplete="off" style="width: 260px; margin: 0px;" type="text">
</td>
<td class="ajax__combobox_buttoncontainer">
<button style="height: 18px; width: 18px; margin: 0px; padding: 0px; visibility: visible;" id="cphCont_cphContAut_ddlTipoJur_ddlTipoJur_Button" type="button"></button>
</td>
</tr>
</tbody>
</table>
<ul id="cphCont_cphContAut_ddlTipoJur_ddlTipoJur_OptionList" class="ajax__combobox_itemlist" style="visibility: hidden; z-index: 1000; overflow: hidden; width: 310px; position: absolute; height: 133px; left: 638px; top: 425px; display: none;">
<li style=""> </li>
<li style="">Cons / Ou</li>
<li style="">Coop</li>
<li style="">Empr Ind</li>
<li style="">Req E</li>
<li>Soc A</li>
<li>Soc E</li>
</ul>
<input name="ctl00$ctl00$cphCont$cphContAut$ddlTipoJur$ddlTipoJur_HiddenField" id="cphCont_cphContAut_ddlTipoJur_ddlTipoJur_HiddenField" value="0" type="hidden">
</div>
In the UIMap.Designer.cs the UL ( I believe ) look like this:
[GeneratedCode("Coded UITest Builder", "12.0.21005.1")]
public class UICphCont_cphConteCustom : HtmlCustom
{
public UICphCont_cphContCustom(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{
#region Search Criteria
this.SearchProperties["TagName"] = "UL";
this.SearchProperties["Id"] = "cphCont_cphContAut_ddlTipoJur_ddlTipoJur_OptionList";
this.SearchProperties[UITestControl.PropertyNames.Name] = null;
this.FilterProperties["Class"] = "ajax__combobox_itemlist";
this.FilterProperties["ControlDefinition"] = "class=\"ajax__combobox_itemlist\" id=\"cphC";
this.FilterProperties["TagInstance"] = "1";
this.WindowTitles.Add("Test");
#endregion
}
Selected LI element looks like this:
public HtmlCustom UISocaCustom
{
get
{
if ((this.mUISocaCustom == null))
{
this.mUISocaCustom = new HtmlCustom(this);
#region Search Criteria
this.mUISocaCustom.SearchProperties["TagName"] = "LI";
this.mUISocaCustom.SearchProperties["Id"] = null;
this.mUISocaCustom.SearchProperties[UITestControl.PropertyNames.Name] = null;
this.mUISocaCustom.FilterProperties["Class"] = null;
this.mUISocaCustom.FilterProperties["ControlDefinition"] = null;
this.mUISocaCustom.FilterProperties["InnerText"] = "Soc A";
this.mUISocaCustom.FilterProperties["TagInstance"] = "6";
this.mUISocaCustom.WindowTitles.Add("tEST");
#endregion
}
return this.mUISocaCustom;
}
}
The code I'm using to replace the login and password with the csv data is :
public void MetdG()
{
this.UIMap.TesterParams.UITxtLoginEditText = TestContext.DataRow["login"].ToString();
this.UIMap.TesterParams.UITxtSenhaEditPassword = Playback.EncryptText(TestContext.DataRow["senha"].ToString());
this.UIMap.Tester();
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
}
Any idea on how to proceed ?
Edit : As instructed by Ryan Cox
It was created a static class to hold the browser window :
[CodedUITest]
public static class GlobalVars
{
public static BrowserWindow myWindow;
}
Test Initializer method was edited to match this change :
[TestInitialize()]
public void BrowserStarter()
{
GlobalVars.myWindow = BrowserWindow.Launch(new Uri("www.google.com"));
}
MainG method was edited so the window could execute the script :
GlobalVars.myWindow.ExecuteScript("var xpath = li[text()='Soca'];var matchingElement = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;);matchingElement.innerHTML = arguments[0];", TestContext.DataRow["type"].ToString());
Now the problem is that the script is throwing an exception. I believe it's because it's searching for the element before it exists ( The test goes thru 2 or 3 pages before this point )

What you're trying to do is change the inner html on a list item, not enter text as you would in your <input> elements, so you'll need to execute a script to do this and modify the DOM. Since it's not a normal action for a user (click on this, enter text there, expand this combo box, etc.), you'll have to use javascript to complete it.
browserWindow.ExecuteScript("var elements = document.getElementsByTagName('li')
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerHTML.indexOf("Soc A") !== -1) {
elements[i].innerHTML = arguments[0];
break;
}
}", TestContext.DataRow["type"].ToString());
//Comment to fill space
Of course, if you had an id on your list items, this would be even easier:
browserWindow.ExecuteScript("document.getElementById("Soc A list item").innerHTML = arguments[0];", TestContext.DataRow["type"].ToString());

Major props to Ryan Cox for all the help he provided yesterday !
The issue got solved with by adding this line of code :
this.UIMap.TestWindow.TestDocument5.UIContCustom.UISocaCustom.
SearchProperties[HtmlCustom.PropertyNames.InnerText] =
TestContext.DataRow["type"].ToString();
Being TestDocument5 the 5th page in the test ( as intended ), UIContCustom the UL element and UISocaCustom the custom HTML element the test generated.
It is worth noting that trying to change the value of InnerText through GetProperty will fail since it will spit out a read-only message.

Related

Position dropdown under button in svelte

I am writing a dropdown component in svelte with tailwind css and i cannot get the dropdown menu to be under the button/anchored to it meaning it always appears under it.
I have tried using relative and other positional tailwind properties but i haven't had any succes.
I am also new to tailwind and mainly have backend experience so this is a bit hard for me if anyone can help or point me towards an example then please do so!
Dropdown example in Svelte
https://svelte.dev/repl/05d770c4baa748b2b0973afec4d59051?version=3.55.1
<script>
// Button binding
let button;
// State
let open = false;
let top = 0, left = 0;
// React to opening
$: if (open) {
setDropdownPosition();
}
function setDropdownPosition() {
const rect = button.getBoundingClientRect();
top = rect.bottom;
left = rect.left;
}
</script>
<button bind:this={button} on:click={() => open = !open}>{!open ? 'Open' : 'Close'} Dropdown!</button>
{#if open}
<ul class="dropdown" style:top={top} style:left={left}>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
{/if}
<style>
/* List Reset */
ul li {
padding: 0;
text-indent: 0;
list-style-type: none;
}
.dropdown {
position: absolute;
display: grid;
gap: 0.25rem;
margin: 0.5rem 0 0 0.5rem;
padding: 0;
}
</style>

Saving Items In Database after receiving a Stripe Webhook

When I receive a webhook from Stripe saying that a subscription was created, I'm trying to update my database to give that user access to my subscription service. The webhook comes in saying that a subscription was created, so I take the UserID and use that to lookup the user in my database. Then I update the user record changing SubscriptionStatus to 1 indicating that it is active. When I try to save that information the database, it throws an exception and I receive an error from Stripe saying that the webhook failed with Error 400 (Bad Request). According to the response from Stripe, it says "The request could not be understood by the server due to malformed syntax."
This is the Response I received from Stripe:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IIS 10.0 Detailed Error - 400.0 - Bad Request</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;}
code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;}
.config_source code{font-size:.8em;color:#000000;}
pre{margin:0;font-size:1.4em;word-wrap:break-word;}
ul,ol{margin:10px 0 10px 5px;}
ul.first,ol.first{margin-top:5px;}
fieldset{padding:0 15px 10px 15px;word-break:break-all;}
.summary-container fieldset{padding-bottom:5px;margin-top:4px;}
legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;}
legend{color:#333333;;margin:4px 0 8px -12px;_margin-top:0px;
font-weight:bold;font-size:1em;}
a:link,a:visited{color:#007EFF;font-weight:bold;}
a:hover{text-decoration:none;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.4em;margin:10px 0 0 0;color:#CC0000;}
h4{font-size:1.2em;margin:10px 0 5px 0;
}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif;
color:#FFF;background-color:#5C87B2;
}#content{margin:0 0 0 2%;position:relative;}
.summary-container,.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
.content-container p{margin:0 0 10px 0;
}#details-left{width:35%;float:left;margin-right:2%;
}#details-right{width:63%;float:left;overflow:hidden;
}#server_version{width:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF;
background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal;
font-size:1em;color:#FFF;text-align:right;
}#server_version p{margin:5px 0;}
table{margin:4px 0 4px 0;width:100%;border:none;}
td,th{vertical-align:top;padding:3px 0;text-align:left;font-weight:normal;border:none;}
th{width:30%;text-align:right;padding-right:2%;font-weight:bold;}
thead th{background-color:#ebebeb;width:25%;
}#details-right th{width:20%;}
table tr.alt td,table tr.alt th{}
.highlight-code{color:#CC0000;font-weight:bold;font-style:italic;}
.clear{clear:both;}
.preferred{padding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em;}
-->
</style>
</head>
<body>
<div id="content">
<div class="content-container">
<h3>HTTP Error 400.0 - Bad Request</h3>
<h4>Bad Request</h4>
</div>
<div class="content-container">
<fieldset><h4>Most likely causes:</h4>
<ul> <li></li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Things you can try:</h4>
<ul> <li>Check the failed request tracing logs for additional information about this error. For more information, click here. </li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Detailed Error Information:</h4>
<div id="details-left">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Module</th><td> ManagedPipelineHandler</td></tr>
<tr><th>Notification</th><td> ExecuteRequestHandler</td></tr>
<tr class="alt"><th>Handler</th><td> System.Web.Mvc.MvcHandler</td></tr>
<tr><th>Error Code</th><td> 0x00000000</td></tr>
</table>
</div>
<div id="details-right">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Requested URL</th><td> https://localhost:44394/Stripe/StripeWebhook</td></tr>
<tr><th>Physical Path</th><td> C:\Users\steve\source\repos\Church Musician Administration App\Church Musician Administration App (Updated)\Stripe\StripeWebhook</td></tr>
<tr class="alt"><th>Logon Method</th><td> Anonymous</td></tr>
<tr><th>Logon User</th><td> Anonymous</td></tr>
</table>
<div class="clear"></div>
</div>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>More Information:</h4>
The request could not be understood by the server due to malformed syntax.
<p>View more information ยป</p>
<p>Microsoft Knowledge Base Articles:</p>
<ul><li></li></ul>
</fieldset>
</div>
</div>
</body>
</html>
This is my Webhook Endpoint in my app:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Database_Access;
using Stripe;
namespace Church_Musician_Administration_App__Updated_.Controllers
{
public class StripeController : Controller
{
private churchmusicianEntities db = new churchmusicianEntities();
[AllowAnonymous]
[HttpPost]
public ActionResult StripeWebhook()
{
try
{
var json = new StreamReader(HttpContext.Request.InputStream).ReadToEnd();
// validate webhook called by stripe only
var stripeEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], "whsec_jLsw8GxNmEKkcyxhjNeDTpJvI5xhggXu");
switch (stripeEvent.Type)
{
case "customer.created":
var customer = stripeEvent.Data.Object as Customer;
// do work
break;
case "customer.subscription.created":
var subscriptionCreated = stripeEvent.Data.Object as Subscription;
string subscriptionCustID = subscriptionCreated.CustomerId;
var subscriptionCustomers = db.logins.Where(x => x.StripeCustomerID == subscriptionCustID);
foreach (var subscriptionCustomer in subscriptionCustomers)
{
if (subscriptionCreated.Status == "trialing" || subscriptionCreated.Status == "active")
{
subscriptionCustomer.SubscriptionStatus = 1;
db.Entry(subscriptionCustomer).State = EntityState.Modified;
db.SaveChanges();
}
}
break;
case "customer.subscription.updated":
case "customer.subscription.deleted":
case "customer.subscription.trial_will_end":
var subscription = stripeEvent.Data.Object as Subscription;
// do work
break;
case "invoice.created":
var newinvoice = stripeEvent.Data.Object as Invoice;
// do work
break;
case "invoice.upcoming":
case "invoice.payment_succeeded":
var successPayment = stripeEvent.Data.Object as Invoice;
string customerID = successPayment.CustomerId;
var custs = db.logins.Where(x => x.StripeCustomerID == customerID);
foreach (var cust in custs)
{
cust.SubscriptionExpiration = successPayment.PeriodEnd.ToString();
db.SaveChanges();
}
break;
case "invoice.payment_failed":
var changeSubscription = stripeEvent.Data.Object as Invoice;
string customerID2 = changeSubscription.CustomerId;
if(changeSubscription.Status != "active")
{
var payingCustomers = db.logins.Where(x => x.StripeCustomerID == customerID2);
foreach (var payingCustomer in payingCustomers)
{
payingCustomer.SubscriptionStatus = 0;
db.SaveChanges();
}
}
// do work
break;
case "coupon.created":
case "coupon.updated":
case "coupon.deleted":
var coupon = stripeEvent.Data.Object as Coupon;
// do work
break;
// DO SAME FOR OTHER EVENTS
}
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
catch (StripeException ex)
{
//_logger.LogError(ex, $"StripWebhook: {ex.Message}");
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
catch (Exception ex)
{
//_logger.LogError(ex, $"StripWebhook: {ex.Message}");
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
}
}
The problem is likely due to something going wrong in your database logic, which is causing your server to return the full error to Stripe, which Stripe cannot read. Instead you should return a 200 early to indicate that the webhook event was received, and then handle your business logic: https://stripe.com/docs/webhooks/build#return-a-2xx-status-code-quickly

How to manage the overflow data in itext 7 when using canvasrenderer

I am using iText 7 to generate pdf file from html file which is saved in a database.
I used the following code to generate pdf, but half of a table which is inside the html file is ignored. I guess the size of IBlockElement which contains the table is bigger than the size of canvas.
Any ideas how to solve the issue?
List<IElement> elements = (List<IElement>)HtmlConverter.ConvertToElements(html);
for (int k = 0; k < elements.Count; k++)
{
if (!renderer.IsFull())
{
canvas.Add((IBlockElement)elements[k]);
}
else
{
page = pdfDoc.AddNewPage();
pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(),pdfDoc);
rectangle = new Rectangle(offset, offset, pageWidth, pageHeight);
pdfCanvas.Rectangle(rectangle);
pdfCanvas.Stroke();
canvas = new iText.Layout.Canvas(pdfCanvas, pdfDoc, rectangle);
renderer = new MyCanvasRenderer(canvas);
canvas.SetRenderer(renderer);
}
}
Implementation of MyCanvasRenderer:
class MyCanvasRenderer : CanvasRenderer {
protected bool full = false;
public MyCanvasRenderer(Canvas canvas) : base(canvas) {
}
public override void AddChild(IRenderer renderer) {
base.AddChild(renderer);
full = true.Equals(GetPropertyAsBoolean(Property.FULL));
}
public bool IsFull() {
return full;
}
}
Canvas class is primarily aimed at cases when you need to add elements to a specific predefined area on a page / XObject and it is not aimed at overflowing your content to next areas.
As the described use case is just converting HTML to PDF, the appropriate API to use is another method of HtmlConverter which allows you to convert HTML to PDF in one line:
HtmlConverter.ConvertToPdf(html, pdfWriter);
UPD: clarifications on additional requirements from #Saeed
Different margins for the first page
CSS allows you to specify page margins with #page media, and those declarations are picked up by pdfHTML. Here is an example of page margins specification and how to customize them for the first page:
#page {
margin-top: 100pt;
margin-left: 36pt;
margin-right: 36pt;
margin-bottom: 36pt;
}
#page:first {
margin-top: 100pt;
margin-left: 36pt;
margin-right: 36pt;
margin-bottom: 36pt;
}
Avoiding splitting of a table across several pages
CSS has page-break-inside property that controls page-wise appearance of elements. In particular, you are interested in page-break-inside: avoid; declaration that prevents splitting of an element across pages.
You could apply this declaration to all tables in your document:
table {
page-break-inside: avoid;
}
Alternatively, you can create your own class and apply it only whenever necessary:
.avoid-page-breaks {
page-break-inside: avoid;
}
<table class="avoid-page-breaks">
...
</table>
Third option is to apply this style to a table inline:
<table style="page-break-inside: avoid;">
...
</table>

Javascript issue in Inventory Transfers and Receipts

i have added a new unbound field to display image of Inventory Item in Transaction Details tab, then to set the fixed height of the image I have added some javascript, but after adding javascript the screen is not populating any default values into like RefNbr and Date, Below is the javascript code am using. The same javascript code is working on my custom screen.
<px:PXJavaScript runat="server" ID="CstJavaScript1" Script="var css = '.GridRow > img { width: 100%; height: 40px; }', head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet){ style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style);" />
Earlier I have added Javascript inside the tab item, but now I moved out of the Tab when it was working without issues.
</px:PXTab>
<px:PXJavaScript runat="server" ID="CstJavaScript1" Script="var css = '.GridRow > img { width: 100%; height: 40px; }', head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet){ style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style);" />

write groovy email template to display parsed build errors in email body

I am using parsed console log plugin and Email-ext plugin in Jenkins to send out daily build status, only upon build failure or compiler warnings. I would like to display the extracted error/warning message in the email body. I got groovy email template from "https://github.com/jenkinsci/email-ext-plugin/blob/master/src/main/resources/hudson/plugins/emailext/templates/groovy-html.template". It display Console Output instead of specific error/warning message want.
I have zero knowledge on groovy or html et al, it gonna take me sometime to learn and able to modify the template to fulfill my need quickly.
Can someone point me a sample file that can search out either console output or parsed console output and only display the lines contain "error" or "warning"?
Any help is greatly appreciated.
Unfortunately, much of the HTML here is quite ugly to be compatible with Outlook limited HTML support.
<%
def paddingForDepth(int depth)
{
return "padding-left:${depth * 30}px";
}
def insertErrorPaneRow(int depth, Closure contents)
{
%>
<tr class="${tableLineClass()}">
<td class="icon_cell"></td>
<td class="console_cell"></td>
<td class="phase_name_cell" style="${paddingForDepth(depth)}">
<table width="100%" class="errorsPane">
<%
contents()
%>
</table>
</td>
</tr>
<%
}
def insertConsoleSummary(def build, int depth)
{
if (build.result != hudson.model.Result.FAILURE)
return;
final BeforeSummary = 0
final SummaryStarted = 1
final SummaryEnded = 2
BufferedReader logReader = new BufferedReader(build.getLogReader());
List<String> errorLines = new LinkedList<String>();
List<String> errorSummary = new LinkedList<String>();
Boolean msBuildDetected = false;
int scanStage = BeforeSummary;
try
{
for (String line = logReader.readLine(); line != null; line = logReader.readLine())
{
if (line.contains(' error ') || line.contains(' warning '))
errorLines.add(line);
if (line.contains('Microsoft (R) Build Engine version '))
msBuildDetected = true;
if (msBuildDetected)
{
switch (scanStage)
{
case BeforeSummary:
if (line.equals('Build FAILED.') || line.equals('Build succeeded.'))
scanStage = SummaryStarted;
if (line.equals('Attempting to cancel the build...'))
{
scanStage = SummaryEnded;
msBuildDetected = false;
}
break;
case SummaryStarted:
if (line ==~ /^\s*\d+ Warning\(s\)/)
scanStage = SummaryEnded;
else
errorSummary.add(line);
break;
}
}
}
}
finally
{
logReader.close();
}
if ((msBuildDetected && (errorSummary.size() > 0)) || (errorLines.size() > 0))
{
insertErrorPaneRow(depth) {
%><tr><td><pre><%
if (msBuildDetected)
errorSummary.each { l -> println l }
else
errorLines.each { l -> println l }
%></pre></td></tr><%
}
}
}
%>
<STYLE>
.icon_cell { padding: 3px; padding-left: 5px; padding-right: 5px; height:16px; vertical-align:middle; }
.console_cell { padding: 3px; padding-left: 5px; padding-right: 15px; height:16px; vertical-align:middle; }
.phase_name_cell { height:16px; vertical-align:middle; }
.errorsPane { background-color:#ffe0e0; }
</STYLE>
<BODY>
<!-- CONSOLE OUTPUT -->
<TABLE width="100%">
<TR><TD class="bg1"><B>BUILD SUMMARY</B></TD></TR>
</TABLE>
<BR/>
<table border="0" class="phasesTable"><tbody>
<%
insertConsoleSummary(build, 0);
%>
</tbody></table>
<BR/>
</BODY>

Resources