chudkins / dsf Goto Github PK
View Code? Open in Web Editor NEWA script to automate working with EFI's Digital StoreFront
License: GNU General Public License v3.0
A script to automate working with EFI's Digital StoreFront
License: GNU General Public License v3.0
Upload-Thumbnail
could be used for category thumbnails as well as products, so it needs to be made more generic and split into Manage-DSF
module.
If a requested page doesn't load, for example because network traffic is heavy or the server is busy, we may get a browser time-out page or something else that is totally not what we're expecting. We need a way to handle this gracefully, maybe by trying again a certain number of times before giving up.
Need better parameter checking, otherwise when called without a browser or web element it will try to find the target and return a null element.
When finished processing a product, update the Excel/CSV with the result of the operation.
Similarly, when beginning to process a product, check if it already has a status so we can run multiple times against the same data set without attempting to redo things that have already been done. For example, if working through a list of 100 items, a browser crash might stop it prematurely, but next time it's run it will notice that 27 items have already been processed and pick up where it left off.
Currently, if Publish-Product
searches for a category and it doesn't find anything, it produces errors due to attempting to set a null radio button, but it cannot tell that the action has failed. Function needs better checking when searching for a category.
Changed empty table detection; needs testing.
When searching for a product name, Find-Product
will only return a hit for an exact match, but if products are found whose name or ID contains the search string it causes a long delay before the function returns. Investigate the reason for this and see if it can be sped up.
For purposes of double-checking the work, and reporting on improved productivity! ๐
See also issue #28; if transactions are tracked they can easily be summarized.
Mass updates of ID/SKU codes could be done using a "New ID" field. If filled, change current ID to new one.
This will be useful for debugging and save me from doing ad-hoc output lines here and there.
Use .PsObject,Properties
to get all properties of whatever, then output them via Format-Table
. This way, we should be able to handle almost anything without coding for anything in particular.
A delay like this usually means we're trying to use a WebDriver or WebElement that has become disconnected. Functions seem to work, but things would be much nicer without this long delay.
Function should validate requested type. For instance, when searching for a radio button we look for type "input" with ID matching the supplied parameter, but it's possible (with poorly designed web app) that ID matches something else instead because it's not unique. After getting a match, function should check that the control is of the requested type.
Add code to add, verify and change security groups.
I found it very helpful when just getting started, however this module provides very little actual functionality. Rewrite code that relies on this module's functions and just handle Selenium calls directly.
$Browser
is defined outside of any function and is therefore available in any function. To avoid unforeseen behavior later, and make script easier to understand, pay better attention to scoping and fix this particular instance.
Output needs to shift from random text on the console to timestamped transactions. Make an object that contains: Date & time; action; result.
Example:
2019-01-30 16:04:28; Add; TEST Product099; Success
2019-01-30 16:04:35; Change; TEST Product024; Fail (DSF refused to accept changes)
Ideally, this object can also be passed to Format-Table
or similar, to be further manipulated. For example, take script output, then sort it by action or result, maybe filter out successful entries so you can see what went wrong.
PS> .\Manage-DsfProduct.ps1 -Credential $Blah -ProductFile .\TestData.csv | where Result -like "Fail*" | format-table -auto
Time Action Product Result
---- ------ ------- ------
1/30/2019 4:04 pm Change TEST Product024 Fail (DSF refused to accept changes)
Find-Product
should return one product that matches the requested Product ID, but instead it is returning anything that contains the Product ID. This results in a false positive, and failure to create a new product, when the ID (and Product Name) is unique but is a substring of an existing ID.
Setup Price isn't being set when the input value is zero.
This function eventually needs to support Fixed, Multiple, and Advanced options.
For Fixed Quantities, you must create or edit a grid similar to the multiple lines on the pricing sheet. Add logic to handle this.
Until then, it's probably best to use "Advanced" option and specify the quantities there. Syntax is similar to regex, so something like "1..5|10|25|100" would work. See the DSF online help for more details.
Interactions with web form elements (checking a box, picking something from a list, etc.) should be wrapped in functions that also check for success of the attempted operation. For instance, when checking a box we need to verify that it is, indeed, checked before proceeding; if it doesn't work as expected, throw an exception instead of just continuing so we can handle it somehow.
Looks like JSON is the way to go here; it's semi-human-readable and handles custom/nested objects as well as XML. Sample config file added; will rename when it's final.
Add function, maybe called Get-Config
or similar, that finds and loads the file if it exists. (If it doesn't exist, companion function Save-Config
or similar should create it with default values.)
Users might wish to change the field names on the input sheet, but that's not easily done because they are hard-coded into the script, such as $Product.Threshold
. Think of some way this could be written such that field names could be changed once and then used in the rest of the script.
When adding a product, we first search to make sure we aren't duplicating an existing name. However, if the new ID gets a match because it's a subset of something else, script just sits there at the search results page.
Check if any of the results is an exact match, and proceed if not.
Related: #15
Add code to handle basic pricing; later, add the trickier options such as price tiers.
Functions needed for this:
Some of these should allow pipelining, so for example Get-PriceRow ... | Set-PriceRow -Price 1.45
, or New-PriceRow | Set-PriceRow 2.87
.
We're probably going to have more scripts to manage things like users and kitted products. Common functions need to be moved into a module so they can be shared. Manage-DSF.psm1
will contain functions that all scripts will need to use.
Sample file should have examples of the different things Manage-DSF
can do.
When the operation is "Skip," script shouldn't care if the product data is valid or empty. This warning probably exists because it's supposed to print "Skipping product [whatever]" but if the ID is empty it can't. The way the warning is written, it implies the product was skipped because the ID is empty, when actually it was instructed to skip.
Fix this to make more sense, ahead of #28 logging rework.
Often the input data contains extra spaces, such as ABC Fac Kit
, so we need to implement a filter such that products won't be created with IDs like that. I think this should be fairly easy using regex.
When adding or updating product, upload an image or "icon" as DSF calls it.
In the case where product ID is changed, Publish-Product will fail to locate the product because we're searching for the old ID. We need to check if it was a "Change ID" operation, and search for the new ID instead if so.
This is the default if not specified, but we need to be able to specifically set this if we're changing a product away from fixed, multiples, etc.
I've learned that $null
is not "like" [System.Management.Automation.Internal.AutomationNull]
, which seems to be what some functions return. Therefore, $blah -like $null
doesn't test correctly.
Go through and check all instances of -like
and -notlike
to ensure they will behave as desired.
Detect if product details page didn't load, and if so check for error message such as "This name already exists" so we can handle it gracefully.
For example, searching for "ABC Widget" you get back "ABC Widget" but also "ABC Widget Press" and "ABC Widgetator"; in this case no product is found.
Certain elements, such as the Manage Inventory checkbox, cause the page to change. (In this case, a section of the form that was disabled becomes enabled.) When this happens, the web element becomes stale and unusable.
In the Manage Inventory example, once the box is checked, when Set-CheckBox
tries to verify it succeeded it cannot, because the reference is now stale.
Set-CheckBox
and some other functions don't know much about the object they're working with, so my idea is to have a function that will look through the element's attributes (Name, ID, etc.) and find one it can use to find the element again.
Maybe there is some attribute, once an element has been found, that can be used to refresh it.
I think if we treat each price row as an entity, storing not only its user-supplied values but entity IDs, it will allow for more flexibility when we need to deal with tiered pricing, multiple sheets, etc.
Look into building an object for this, as it could be helpful to have member functions. Either way, I'm wanting to allow something like this:
$PriceSheet | Get-PriceRow -RangeBegin $Qty | Set-PriceRow -NewPrice $Cost -Setup $SetupFee
It would be nice if this script could import data directly from Excel files, instead of requiring the input to be CSV.
One reason is that some product detail fields are rich text, and formatting is lost when exporting to CSV. Another reason is that testing becomes more tedious with the additional step of exporting the test data to CSV.
Setting -Debug
when running should produce loads of debugging text, but it doesn't output anything more than usual except "Debug: True" at the beginning.
Today Firefox started but didn't load the URL at all.
New-Object : Exception calling ".ctor" with "0" argument(s): "The HTTP request to the remote WebDriver server for URL
http://localhost:64968/session timed out after 60 seconds."
At C:\Program Files\WindowsPowerShell\Modules\Selenium\1.1\Selenium.psm1:18 char:19
+ ... $Driver = New-Object -TypeName "OpenQA.Selenium.Firefox.FirefoxDriv ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
Entire script crashed as a result of not finding the login fields or anything else. Figure out how to handle this more gracefully.
Script lacks help, or even any comments, regarding the purpose of its parameters.
If only these two fields have data, product settings should be skipped because they won't be affected.
Perhaps optionally, script should accept a PSCredential object for better security. Credentials from the command line could be scraped from get-process
or by other means, so some people might prefer to use a credential object.
My attempt to catch if image type is supported does not work. When I supply a PDF as the thumbnail, DSF does not support this, but my test of -in
supported image types is succeeding where it should fail.
It works in a rudimentary way, by invoking the iFrame's Click() event, which causes it to set focus on the text field. In the future, we will want to be able to input formatted text, so this function will need to be revamped after the rest of the script is actually working.
Many things about kitted products can be changed just like non-printed ones, such as image and description. However, there is an additional step between the product details and being able to finish editing; for a kit you'll have a "Next" button instead of "Finish." Update-Product
should check if the current product is a kit, and skip through the "Products in Kit" section on its way to saving changes.
Need a reliable way of detecting if requested page has loaded completely. Example: After login page, storefront page begins to load; admin link is found but can't be clicked yet because "loading spinner" obscures it.
We need a way to wait until the element we want is available, which in this case means the "loading spinner" has cleared because the in-page scripts are satisfied it's done. Can we also wait for this, maybe by spying on the script?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.