PageFactory is returning old values - appium

Project - mobile automation,
tools - appium, pagefactory
I have an field which returns Account balance for logged in user. My test checks for new balance after successful transaction.
to assert amount calcualtion I am storing balanceBeforeTransaction and balanceAfterTransaction
#AndroidFindBy(xpath="//*[contains(#text,\'balance\')]")
public WebElement balance;
balanceBeforeTransaction = balance.getText();
transaction()
balanceAfterTransaction = balance.getText();
My transaction is succesfull and I can see new balance in mobile app but my code is returning same (old) value for both the fields i.e balanceBeforeTransaction and balanceAfterTransaction. Not sure why it is not picking latest value.
Note: I havent used #CahceLookup, If pagefactory uses it by default then how can I disable it

Related

Is it possible to call an URL passing website parameters?

I am writing code for a custom SAP program regarding some Vendor information. In my program flow, there is a possibility of me trying to use a Vendor VAT Number that belongs to an unknown Vendor. There is a Web site (EU Based - https://ec.europa.eu/taxation_customs/vies/) for such purposes that requires a country key and the specified VAT Number in order for it to provide an answer with the available Company information (only works for company VAT numbers of course). My problem is that I cannot seem to find any way to pass those parameters dynamically to the Web site without needing the user to interfere during this process. Manually, the process would be to select a country key, type in a VAT number and press 'Verify'.
Is there any way for me to call this specific Web site URL and "bypass" this process to only display the result page? For now, I'm using the following Function Module to just call the specified URL, in lack of any better choices.
call function 'CALL_INTERNET_ADRESS'
exporting
pi_adress = 'https://ec.europa.eu/taxation_customs/vies/'
exceptions
no_input_data = 1
others = 2.
You can use CL_HTTP_CLIENT class or HTTP_POST/HTPP_GET FM.
You need to install given web page SSL root certificate to your system with STRUST t-code.
Example usage of CL_HTTP_CLIENT below.
DATA: lv_url TYPE string VALUE 'http://mkysoft.com/ip.php'.
DATA: o_client TYPE REF TO if_http_client.
DATA: lv_http_rc TYPE i.
DATA: lv_reason TYPE string.
DATA: lt_fields TYPE tihttpnvp.
TRY.
cl_http_client=>create_by_url( EXPORTING
url = lv_url
IMPORTING
client = o_client
EXCEPTIONS
OTHERS = 0 ).
o_client->request->get_header_fields( CHANGING fields = lt_fields ).
o_client->request->set_header_field( name = '~request_uri' value = '/ip.php' ).
o_client->request->set_header_field( name = '~host' value = 'mkysoft.com' ).
o_client->request->set_method( if_http_request=>co_request_method_get ).
o_client->send( ).
o_client->receive( ).
o_client->response->get_status( IMPORTING
code = lv_http_rc
reason = lv_reason ).
* Error check
IF lv_http_rc = 200.
DATA(lv_xml) = o_client->response->get_cdata( ).
* Handle error
ELSE.
WRITE: / 'Fehler: ', lv_http_rc.
ENDIF.
o_client->close( ).
CATCH cx_root INTO DATA(e_txt).
WRITE: / e_txt->get_text( ).
ENDTRY.
EU Commission has a SOAP service for vat numbers.
See the info page
https://ec.europa.eu/taxation_customs/vies/technicalInformation.html
and that it even supports http
http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl
You have a non screen scrape method, proper interface you should look at.
On the other point of Avoiding SSL.
Make a basic guide for customers to add the European commission cert to their SAP system. If someone is complaining about that, then they are a serious user of the internet. Every sap on premise user, that needs to call the internet adds certs.
Http is dead....

How do I find the Conversion Action ID for use in the Google Ads API?

I'm using the latest (v7) Google Ads API to upload offline conversions for Google Ads, using the Python Client Library. This is the standard code I'm using:
import os
from google.ads.googleads.client import GoogleAdsClient
client = GoogleAdsClient.load_from_env(version='v7')
def process_adwords_conversion(
conversion_date_time,
gclid,
conversion_action_id,
conversion_value
):
conversion_date_time = convert_datetime(conversion_date_time)
customer_id = os.environ['GOOGLE_ADS_LOGIN_CUSTOMER_ID']
click_conversion = client.get_type("ClickConversion")
conversion_action_service = client.get_service("ConversionActionService")
click_conversion.conversion_action = (
conversion_action_service.conversion_action_path(
customer_id, conversion_action_id
)
)
click_conversion.gclid = gclid
click_conversion.conversion_value = float(conversion_value)
click_conversion.conversion_date_time = conversion_date_time
click_conversion.currency_code = "USD"
conversion_upload_service = client.get_service("ConversionUploadService")
request = client.get_type("UploadClickConversionsRequest")
request.customer_id = customer_id
request.conversions = [click_conversion]
request.partial_failure = True
conversion_upload_response = (
conversion_upload_service.upload_click_conversions(
request=request,
)
)
uploaded_click_conversion = conversion_upload_response.results[0]
print(conversion_upload_response)
print(
f"Uploaded conversion that occurred at "
f'"{uploaded_click_conversion.conversion_date_time}" from '
f'Google Click ID "{uploaded_click_conversion.gclid}" '
f'to "{uploaded_click_conversion.conversion_action}"'
)
return False
I believe the code is fine, but I'm having problems locating the conversion_action_id value to use. In the Google Ads UI there's a screen listing the different Conversion Actions, with no sign of an ID anywhere. You can click on the name and get more details, but still no ID:
The conversion action detail screen in Google Ads UI
I've tried the following:
Using the ocid, ctId, euid, __u, uscid, __c, subid URL parameters from this detail page as the conversion_action_id. That always gives an error:
partial_failure_error {
code: 3
message: "This customer does not have an import conversion action that matches the conversion action provided., at conversions[0].conversion_action"
details {
type_url: "type.googleapis.com/google.ads.googleads.v7.errors.GoogleAdsFailure"
value: "\n\305\001\n\003\370\006\t\022dThis customer does not have an import conversion action that matches the conversion action provided.\0320*.customers/9603123598/conversionActions/6095821\"&\022\017\n\013conversions\030\000\022\023\n\021conversion_action"
}
}
Using the standard Google answer:
https://support.google.com/google-ads/thread/1449693/where-can-we-find-google-ads-conversion-ids?hl=en
Google suggests creating a new Conversion Action and obtaining the ID in the process. Unfortunately their instructions don't correspond to the current UI version, at least for me. The sequence I follow is:
Click the + icon on the Conversion Actions page
Select "Import" as the kind of conversion I want
Select "Other data sources or CRMs" then "Track conversions from clicks"
Click "Create and Continue"
I then get the screen:
Screen following Conversion Action creation
The recommended answer says:
The conversion action is now created and you are ready to set up the tag to add it to your website. You have three options and the recommended answer in this thread is discussing the Google Tag Manager option, which is the only option that uses the Conversion ID and Conversion Label. If you do not click on the Google Tag Manager option you will not be presented with the Conversion ID and Conversion Label.
Not so! What three options? The first "Learn more" link mentions the Google Tag Manager, but in the context of collecting the GCLID, which I already have. The "three options" mentioned in the official answer have gone. Clicking "done" simply takes me back to the Conversion Actions listing.
Using the REST API
I've tried authenticating and interrogating the endpoint:
https://googleads.googleapis.com/v7/customers/9603123598/conversionActions/
hoping that would give a list of conversion actions, but it doesn't. It just gives a 404.
Does anybody know a way of getting the Conversion Action ID, either from the UI or programmatically (via client library, REST or some other method)?
Thanks!
If you're using Python, you can list your conversions via next snippet:
ads: GoogleAdsServiceClient = client.get_service('GoogleAdsService')
pages = ads.search(query="SELECT conversion_action.id, conversion_action.name FROM conversion_action", customer_id='YOUR_MCC_ID')
for page in pages:
print(page.conversion_action)
You can also open conversion action in UI and locate &ctId=, that's the conversion action id.
I found this post with the solution how to get the Conversion Action ID:
(…) I found out that conversionActionId can be found also in Google
Ads panel. When you go to conversion action details, in URL there is
parameter "ctId=123456789" which represent conversion action id.
By the way, I tried something similar and it's still not working, but with this Conversion Action ID I get a different "Partial Failure" message, at least.
At least in Google Ads API (REST) v10,
it works if field conversionAction is set with value:
'customers/{customerId}/conversionActions/{ctId}'
customerId - without hyphens
ctId - conversion action id, as mentioned in above comments,
taken from GET parameters in Google Ads panel when specific conversion is opened.
Can also be found programmatically with API method.

Time on page calculated only for specific segment in Adobe Analytics

Goal
I would like to see what is the time on page for user who is logged in. Eliminate from reports time, while user was not logged in.
To have ability to distinguish between time on page while user is not logged in and time on page while he is logged in.
Setup
Let's say we have:
Traffic variable User logged in as a prop1 where is true or false.
Traffic variable Time from previous event as a prop2 in seconds
eVar1 duplicating prop1 | expire after event5
eVar2 duplicating prop2 | expire after event5
event4 - User logged in
event5 - User logged out
Time between events
From an article about measuring time between events (https://experienceleaguecommunities.adobe.com/t5/adobe-analytics-questions/calculate-time-between-success-events/qaq-p/302787)
if (s.events && (s.events + ",").indexOf("event4,") > -1) {
s.prop2 = "start"
}
if (s.events && (s.events + ",").indexOf("event5,") > -1) {
s.prop2 = "stop"
}
s.prop2 = s.getTimeToComplete(s.prop2, "TTC", 0);
s.getTimeToComplete = new Function("v", "cn", "e", "var s=this,d=new Date,x=d,k;if(!s.ttcr){e=e?e:0;if(v=='start'||v=='stop')s.ttcr=1;x.setTime(x.getTime()+e* 86400000);if(v=='start'){s.c_w(cn,d.getTime(),e?x:0);return '';}if(v=='stop'){k=s.c_r(cn);if(!s.c_w(cn,'',d)||!k)return '';v=(d.getTime()-k)/1000;var td=86400,th=3600,tm=60,r=5,u,un;if(v>td){u=td;un='days';}else if(v>th){u=th;un='hours';}else if(v>tm){r=2;u=tm;un='minutes';}else{r=.2;u=1;un='seconds';}v=v*r/u;return (Math.round(v)/r)+' '+un;}}return '';");
Time spent overview
From adobe docs (https://docs.adobe.com/content/help/en/analytics/components/metrics/time-spent.html)
A “sequence” is a consecutive set of hits where a given variable
contains the same value (whether by being set, spread forward, or
persisted). For example, prop1 “A” has two sequences: hits 1 & 2 and
hit 6. Values on the last hit of the visit do not start a new sequence
because the last hit has no time spent. Average time spent on site
uses sequences in the denominator.
So I guess I will uses prop1 as a denominator for logged in user state to count time between event in prop2 properly.
Problem
I am not pretty sure, If this approach is enough to correctly measure time spent only while user is logged in. I would appreciate some hints, how to set up eVars correctly or if I understand sequence denominator correctly.
I also set up eVars with terminating event5, but I am not sure, If this leads to desired behavior.
If you also solve this problem before, please can you lead me, how you define your segment or condition in reports.
GetTimeBetweenEvents plugin should do a job. However, it seems like it was rewritten, I have found in documentation example calls also using Launch plugins extension:
https://docs.adobe.com/content/help/en/analytics/implementation/vars/plugins/gettimebetweenevents.html
From Adobe documentation
Install the plug-in using AppMeasurement Copy and paste the following
code anywhere in the AppMeasurement file after the Analytics tracking
object is instantiated (using s_gi ). Preserving comments and version
numbers of the code in your implementation helps Adobe with
troubleshooting any potential issues.
/******************************************* BEGIN CODE TO DEPLOY *******************************************/
/* Adobe Consulting Plugin: getTimeBetweenEvents v2.1 (Requires formatTime and inList plug-ins) */
s.getTimeBetweenEvents=function(ste,rt,stp,res,cn,etd,fmt,bml,rte){var s=this;if("string"===typeof ste&&"undefined"!==typeof rt&&"string"===typeof stp&&"undefined"!==typeof res){cn=cn?cn:"s_tbe";etd=isNaN(etd)?1:Number(etd);var f=!1,g=!1,n=!1, p=ste.split(","),q=stp.split(",");rte=rte?rte.split(","):[];for(var h=s.c_r(cn),k,v=new Date,r=v.getTime(),c=new Date,a=0; a<rte.length;++a)s.inList(s.events,rte[a])&&(n=!0);c.setTime(c.getTime()+864E5*etd);for(a=0;a<p.length&&!f&&(f=s.inList(s.events,p[a]),!0!==f);++a);for(a=0;a<q.length&&!g&&(g=s.inList(s.events,q[a]),!0!==g);++a);1===p.length&&1===q.length&&ste===stp&&f&&g?(h&&(k=(r-h)/1E3),s.c_w(cn,r,etd?c:0)):(!f||1!=rt&&h||s.c_w(cn,r,etd?c:0),g&&h&&(k=(v.getTime()-h)/1E3,!0===res&&(n=!0)));!0===n&&(c.setDate( c.getDate()-1),s.c_w(cn,"",c));return k?s.formatTime(k,fmt,bml):""}};
/* Adobe Consulting Plugin: formatTime v1.1 (Requires inList plug-in) */
s.formatTime=function(ns,tf,bml){var s=this;if(!("undefined"===typeof ns||isNaN(ns)||0>Number(ns))){if("string"===typeof tf&&"d"===tf||("string"!==typeof tf||!s.inList("h,m,s",tf))&&86400<=ns){tf=86400;var d="days";bml=isNaN(bml)?1:tf/(bml*tf)} else"string"===typeof tf&&"h"===tf||("string"!==typeof tf||!s.inList("m,s",tf))&&3600<=ns?(tf=3600,d="hours", bml=isNaN(bml)?4: tf/(bml*tf)):"string"===typeof tf&&"m"===tf||("string"!==typeof tf||!s.inList("s",tf))&&60<=ns?(tf=60,d="minutes",bml=isNaN(bml)?2: tf/(bml*tf)):(tf=1,d="seconds",bml=isNaN(bml)?.2:tf/bml);ns=Math.round(ns*bml/tf)/bml+" "+d;0===ns.indexOf("1 ")&&(ns=ns.substring(0,ns.length-1));return ns}};
/* Adobe Consulting Plugin: inList v2.1 */
s.inList=function(lv,vtc,d,cc){if("string"!==typeof vtc)return!1;if("string"===typeof lv)lv=lv.split(d||",");else if("object"!== typeof lv)return!1;d=0;for(var e=lv.length;d<e;d++)if(1==cc&&vtc===lv[d]||vtc.toLowerCase()===lv[d].toLowerCase())return!0;return!1};
/******************************************** END CODE TO DEPLOY ********************************************/
Then your eVar may looks like:
s.eVar1 = s.getTimeBetweenEvents("event1", true, "event2", true, "", 0, "s", 2, "event3");

Unit Price Attribute Not Visible in Quickbooks Desktop API

I don't see the Unit Price attribute available in the Item Class when it comes to QBD. Its available in QBO. I am trying to download and fill a database using the items entered via Quickbooks desktop version. Can someone help please?
How can I get the Unit Price for an item in Intuit.Ipp.Data.Qbd.Item?
Extra Information Added after comment by Shivan Raptor (7-Nov-2013)
I am having a Quickbooks Pro Trial 2014 UK version installed in my computer. I have created a company file and items for the company. When I create an item I can enter a Price to that item. Quickbooks must be saving it somewhere. I need to access it using the Quickbooks API from my .Net application.
I am interested on the stock items here. I am using Intuit.Ipp.Data.Qbd.Item class to access it. Am I using the right class? If you go to the API documentation the Item class has a field called Unit Price but its not listed when you actually check from the .Net application.
Shivan Raptor wanted the code (8-Nov-2013)
Given below is the code snippet. If you understand the question properly you would realize it cannot give a run time error because you cannot compile a code if you write it with object attributes that are not exposed. And the compiler error is kind of obvious too:
ATTRIBUTE_NAME not present in CLASS_NAME
In this case, ATTRIBUTE_NAME = UnitPrice and CLASS_NAME = Intuit.Ipp.Data.Qbd.Item (this is already there in the first post itself)
The relevant code sample is given below. Its the code behind of an ASP.Net page.
Try
Dim varItemBL As New BL.ItemManagement
'Preparing Query
Dim qbdItemQuery As New Intuit.Ipp.Data.Qbd.ItemQuery
qbdItemQuery.ItemElementName = Intuit.Ipp.Data.Qbd.ItemChoiceType4.StartPage
qbdItemQuery.Item = "1"
qbdItemQuery.ChunkSize = "10"
'Quering Quickbooks Desktop
Dim qbdItems = qbdItemQuery.ExecuteQuery(Of Intuit.Ipp.Data.Qbd.Item)(context).ToList
'Synchronising Items from Quickbooks to MyDigiRep
For i As Integer = 0 To qbdItems.Count - 1
Dim varUnitPrice As Decimal
'Checking whether Unit Price is entered
If qbdItems(i).UnitPrice Is Nothing Then
varUnitPrice = 0
Else
varUnitPrice = qbdItems(i).UnitPrice.Amount
End If
'Synchronising Item with the MyDigiRep database
varItemBL.fnAddItemsAPI(qbdItems(i).Name, "NS", varUnitPrice, _
qbdItems(i).UOMAbbrv, HttpContext.Current.Session("companyID"), _
qbdItems(i).Id.Value)
Next
'Updating UI to display synchronisation results
lblItemSycnStatus.Text = qbdItems.Count & " Item Records Synchronised."
Catch ex As Exception
lblItemSycnStatus.Text = "Item Records Synchronisation Failed."
End Try
The version of the Intuit.Ipp.Data.dll is 2.1.12.0

Posting date issue due to time zones and the use of SystemDateGet()

Summary
We are experiencing a problem where the systemDateGet() function is returning the
AOS wher the local date is required when determining the date for posting purposes.
Details
We have branches around the world, both sides of the international date line, with
users connecting to local terminal servers with the appropriate time zone settings
for the user's branch.
Each branch is associated with a different company, which has been configured with
the correct time zone.
We run a single AOS with the time zone setting set for the head office. There is
not an option to introduce additional AOS's.
The SystemDateGet() function is returning the AOS date as the user is not changing
their Axapta session date.
A number of system fields in the database related to posting dates are DATE based and
not UTCDATETIME based.
We are running AX2009 SP1 RU7.
Kernel version 5.0.1500.4570
Application version 5.0.1500.4570
Localization version: Brazil, China, Japan, Thailand, India
I am aware that the SystemDateGet() function was designed to return the AOS date unless
the user changes their session date in which case that date is returned.
Each user has the appropriate time zone setting in there user profile.
Problem
One example of the problem is when a user attempts to post a journal involving financial
transactions, where the ledger period is checked to see if it is open. For example,
the user is in England attempting to post a journal at 3:00pm on the 30st of November, local
time, the standard Axapta code uses the systemDateGet() function to determine the date to use
in the validation (determining if the period is open). In our case, the AOS is based in
Brisbane Australia and the systemDateGet() function is returning the 1st of December
(local time 1:00am on the 1st of December).
Another example of the problem is where an invoice is posted in the United States on a Friday
and the day of the week where the AOS is situated is a Saturday. We need the system to
record the local date.
Question
Besides rewriting all system code involving systemDateGet(), over 2000 entities, is there
any other options that can be used to get around the problem of getting the correct local
date?
Solution limitations.
In the example given above of the ledger period being closed, it is not possible from a
business practices standpoint to open the next period before end of month processing
has been completed.
There is currently no option for the purchase of additional AOS's.
Create a function in the Global class:
static date systemDateGetLocal()
{
return DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::utcNow(), DateTimeUtil::getUserPreferredTimeZone()));
}
Then in Info.watchDog() do a:
systemDateSet(systemDateGetLocal());
This may only be a partial solution, the watchDog is executed on the client side only.
Here is a quick update. Let me know if there are any issues or situations that need to be addressed.
USING LOCAL TIME
Introduction:
The following is a work in progress update, as the solution has yet to be fully tested in all situations.
Problem:
If the user has a different time zone to the AOS, the timeNow() and systemDateGet() functions are returning the AOS details when the local date time is required.
Clarifiers:
When the local date time is changed within Axapta, the systemDateGet() function will return the local date, however the timeNow() function still returns the AOS time.
Coding changes:
A number of coding changes have been made to handle a number of different situations. Comments will be added where an explanation may be required.
The brackets were changed to { and } to allow this to be posted.
CLASS:GLOBAL
One requirement I was given was to allow the system to handle multiple sites within a company that may have different time zones. Presently this functionality is not required.
static server void setSessionDateTime(
inventSiteId inventSiteId = '',
utcDateTime reference = dateTimeUtil::utcNow())
{
str sql;
sqlStatementExecutePermission perm;
connection conn = new UserConnection();
timeZone timeZone;
int ret;
;
if (inventSiteId)
{
timeZone = inventSite::find(inventSiteId).Timezone;
}
else
{
timeZone = dateTimeUtil::getCompanyTimeZone();
}
//This is to get around the kernel validation of changing timezones
//when the user has more than one session open.
sql = strfmt("Update userInfo set preferredTimeZone = %1 where userInfo.id = '%2'", enum2int(timeZone), curUserId());
perm = new SQLStatementExecutePermission(sql);
perm.assert();
ret = conn.createStatement().executeUpdate(sql);
dateTimeUtil::setUserPreferredTimeZone(timeZone);
dateTimeUtil::setSystemDateTime(reference);
CodeAccessPermission::revertAssert();
}
static int localTime()
{
utcDateTime tmp;
;
setSessionDateTime();
tmp = dateTimeUtil::applyTimeZoneOffset( dateTimeUtil::utcNow(), dateTimeUtil::getCompanyTimeZone());
return dateTimeUtil::time(tmp);
}
The following method was implemented as a cross check to ensure that systemDateGet() returns the expected value.
static date localDate()
{
utcDateTime tmp;
;
setSessionDateTime();
tmp = dateTimeUtil::applyTimeZoneOffset( dateTimeUtil::utcNow(), dateTimeUtil::getCompanyTimeZone());
return dateTimeUtil::date(tmp);
}
CLASS:APPLICATION
Modify the method setDefaultCompany. Add the line setSessionDateTime(); directly after the super call. This is to allow the time to change when the user changes company (another requirement I was given).
CLASS:INFO
So that the system uses the correct date/time from the start of the session.
void startupPost()
{
;
setSessionDateTime();
}
Modify the method canViewAlertInbox() adding the line setSessionDateTime(); as the first line. This is to handle if the user has multiple forms open for different companies.
Localization dependent changes:
Depending on your service pack and localizations, you will need to change a function of objects to use the localTime() function, replacing timeNow(). IMPORTANT NOTE: Do not change the class BatchRun to use the new localTime function as this will stop it working correctly.
In our system there were around 260 instances that could be changed. If you do not use all modules and localizations the actual number of lines you need to change will be less.
Final note:
There are a number of today() calls in the code. I have not yet gone through each line to ensure it is coded correctly, i.e. using today() instead of systemDateGet().
Known issues:
I have come across a situation where the timezone change function did not work completely as expected. This was when one session was doing a database synchronisation and another session was opened in a different company. As normal users will never be able to do this, I have not spent much time on its solution at this stage. It is something I do intend to resolve.

Resources