diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt index ebe8501337eff..8587abefba576 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt @@ -199,3 +199,4 @@ Magento/Framework/MessageQueue/Publisher/Config/PublisherConfigItem Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem IntegrationConfig.php *Test.php +setup/performance-toolkit/aggregate-report diff --git a/setup/performance-toolkit/README.md b/setup/performance-toolkit/README.md new file mode 100644 index 0000000000000..2c1c92d4ca919 --- /dev/null +++ b/setup/performance-toolkit/README.md @@ -0,0 +1,311 @@ +## Performance Toolkit + +## Overview + +The Performance Toolkit enables you to test the performance of your Magento installations and the impact of your customizations. It allows you to generate sample data for testing performance and torun Apache JMeter scenarios, which imitate users activity. As a result, you get a set of metrics, that you can use to judge how changes affect performance, and the overall load capacity of your server(s). + +## Installation + +### Apache JMeter + +- Go tothe [Download Apache JMeter](http://jmeter.apache.org/download_jmeter.cgi) page and download JMeter in the *Binaries* section. Note that Java 8 or later is required. +- Unzip the archive. + +### JSON Plugins +- Go to the [JMeter Installing Plugins](https://jmeter-plugins.org/install/Install/) page. +- Download `plugins-manager.jar` and put it into the `{JMeter path}/lib/ext` directory. Then restart JMeter. +- Follow the instructions provided on the [JMeter Plugins Manager](https://jmeter-plugins.org/wiki/PluginsManager/) page to open Plugins Manager. +- Select *Json Plugins* from the plugins listed on the *Available Plugins* tab, then click the *Apply changes and restart JMeter* button. + +## Quick Start + +Before running the JMeter tests for the first time, you will need to first use the `php bin/magento setup:performance:generate-fixtures {profile path}` command to generate the test data. You can find the configuration files of available profiles in the folders `setup/performance-toolkit/profiles/ce` and `setup/performance-toolkit/profiles/ee`. + +It can take a significant amount of time to generate a profile. For example, generating the medium profile takes up to 6 hours, while generating the large profile can take up to 22 hours. So we recommend using the `-s` option to skip indexation. Then you can start indexation manually. + +Splitting generation and indexation processes doesn't reduce total processing time, but it requires fewer resources. For example, to generate a small profile, use commands: + + php bin/magento setup:performance:generate-fixtures -s setup/performance-toolkit/profiles/ce/small.xml + php bin/magento indexer:reindex + +For more information about the available profiles and generating fixtures generation, read [Generate data for performance testing](http://devdocs.magento.com/guides/v2.2/config-guide/cli/config-cli-subcommands-perf-data.html). + +**Note:** Before generating medium or large profiles, it may be necessary to increase the value of `tmp_table_size` and `max_heap_table_size` parameters for MySQL to 512Mb or more. The value of `memory_limit` for PHP should be 1Gb or more. + +There are two JMeter scenarios located in `setup/performance-toolkit` folder: `benchmark.jmx` and `benchmark_2015.jmx` (legacy version). + +**Note:** To be sure that all quotes are empty, run the following MySQL query before each run of a scenario: + + UPDATE quote SET is_active = 0 WHERE is_active = 1; + +### Run JMeter scenario via console + +The following parameters can be passed to the `benchmark.jmx` scenario: + +| Parameter Name | Default Value | Description | +| --------------------------------- | ------------------- | ---------------------------------------------------------------------------------------- | +| host | | URL component 'host' of application being tested (URL or IP). | +| base_path | | Base path for tested site. | +| admin_path | backend | Admin backend path. | +| admin_user | admin | Admin backend user. | +| admin_password | 123123q | Admin backend password. | +| customer_password | 123123q | Storefront customer password. | +| customers_page_size | 20 | Page size for customers grid in Magento Admin. | +| files_folder | ./files/ | Path to various files that are used in scenario (`setup/performance-toolkit/files`). | +| loops | 1 | Number of loops to run. | +| orders_page_size | 500 | Page size for orders grid. | +| test_duration | 900 | Total duration (s) of scenario execution. | +| numberOfThreads | 48 | Total number of all threads. | +| frontEndPoolPercentage | 90 | Percentage of Frontend Pool. | +| adminPoolPercentage | 10 | Percentage of Admin Pool. | +| browseCatalogPercentage | 30 | Percentage of threads in Frontend Pool that emulate catalog browsing activities. | +| siteSearchPercentage | 30 | Percentage of threads in Frontend Pool that emulate catalog search activities. | +| checkoutByGuestPercentage | 4 | Percentage of threads in Frontend Pool that emulate checkout by guest. | +| checkoutByCustomerPercentage | 4 | Percentage of threads in Frontend Pool that emulate checkout by customer. | +| addToCartPercentage | 28 | Percentage of threads in Frontend Pool that emulate abandoned cart activities. | +| addToWishlistPercentage | 2 | Percentage of threads in Frontend Pool that emulate adding products to Wishlist. | +| compareProductsPercentage | 2 | Percentage of threads in Frontend Pool that emulate products comparison. | +| productCompareDelay | 0 | Delay (s) between iterations of product comparison. | +| promotionRulesPercentage | 10 | Percentage of threads in Admin Pool that emulate creation of promotion rules. | +| adminPromotionsManagementDelay | 0 | Delay (s) between creation of promotion rules. | +| merchandizingPercentage | 50 | Percentage of threads in Admin Pool that emulate merchandizing activities. | +| adminProductManagementPercentage | 90 | Percentage of threads in Merchandizing Pool that emulate product management activities. | +| adminCategoryManagementPercentage | 10 | Percentage of threads in Merchandizing Pool that emulate category management activities. | +| adminProductEditingPercentage | 60 | Percentage of threads in Product Management Pool that emulate product editing. | +| adminProductCreationPercentage | 40 | Percentage of threads in Product Management Pool that emulate creation of products. | +| adminCategoryManagementDelay | 0 | Delay (s) between iterations of category management activities. | +| apiProcessOrdersPercentage | 30 | Percentage of threads in Admin Pool that emulate orders processing activities. | +| adminProcessReturnsPercentage | 10 | Percentage of threads in Admin Pool that emulate creation/processing of returns. | +| csrPoolPercentage | 0 | Percentage of CSR Pool. | +| csrBrowseCustomersPercentage | 10 | Percentage of threads in CSR Pool that emulate customers browsing activities. | +| csrCreateOrderPercentage | 70 | Percentage of threads in CSR Pool that emulate creation of orders. | +| csrCreateProcessReturnsPercentage | 20 | Percentage of threads in CSR Pool that emulate creation/processing of returns. | +| csrCreateProcessReturnsDelay | 0 | Delay (s) between creation of returns. | +| wishlistDelay | 0 | Delay (s) between adding products to Wishlist. | +| categories_count | 200 | Total number of categories that are be used in scenario. | +| simple_products_count | 30 | Total number of simple products that are be used in scenario. | +| nested_categories_count | 50 | Total number of last-level categories that can be used in scenario. | + +Parameters must be passed to command line with the `J` prefix: + +`-J{parameter_name}={parameter_value}` + +The required parameters are `{host}` and `{base_path}`. All other parameters are optional. If you do not pass any custom value, a default value will be used. + +There are some options that you should pass to JMeter in the console mode: + +`-n` Run scenario in Non-GUI mode +`-t` Path to the JMX file to be run +`-l` Path to the JTL file to log sample results to +`-j` Path to JMeter run log file + +To get more details about available JMeter options, read [Non-GUI Mode](http://jmeter.apache.org/usermanual/get-started.html#non_gui). + +For example, you can run a scenario via console with 100 threads for 5 minutes as follows: + + cd {JMeter path}/bin/ + jmeter -n -t {path to peformance toolkit}/benchmark.jmx -j ./jmeter.log -l ./jmeter-results.jtl -Jhost=magento2.dev -Jbase_path=/ -Jadmin_path=admin -Jtest_duration=300 -JnumberOfThreads=100 + +As a result, you will get `jmeter.log` and `jmeter-results.jtl`. The`jmeter.log` contains information about the test run and can be helpful in determining the cause of an error. The JTL file is a text file containing the results of a test run. It can be opened in GUI mode to perform analysis of the results (see the *Output* section below). + + +The following parameters can be passed to the `benchmark_2015.jmx` scenario: + +| Parameter Name | Default Value | Description | +| -------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| host | localhost | URL component 'host' of application being tested (URL or IP). | +| base_path | / | Base path for tested site. | +| report_save_path | ./ | Path where reports will be saved. Reports will be saved in current working directory by default. | +| ramp_period | 300 | Ramp period (seconds). Period the request will be distributed within. | +| orders | 0 | Number of orders in the period specified in the current allocation. If `orders` is specified, the `users` parameter will be recalculated. | +| users | 100 | Number of concurrent users. Recommended amount is 100. Minimal amount is 10. | +| view_product_add_to_cart_percent | 62 | Percentage of users that will only reach the add to cart stage. | +| view_catalog_percent | 30 | Percentage of users that will only reach the view catalog stage. | +| guest_checkout_percent | 4 | Percentage of users that will reach the guest checkout stage. | +| customer_checkout_percent | 4 | Percentage of users that will reach the (logged-in) customer checkout stage. | +| loops | 1 | Number of loops to run. | +| admin_path | admin | Admin backend path. | +| admin_user | admin | Admin backend user. | +| admin_password | 123123q | Admin backend password. | +| think_time_deviation | 1000 | Deviation (ms) for "think time" emulation. | +| think_time_delay_offset | 2000 | Constant delay offset (ms) for "think time" emulation. | + +### Run JMeter scenario via GUI + +**Note:** Use the GUI mode only for scenario debugging and viewing reports. Use the console mode for real-life load testing, because it requires significantly fewer resources. + +- Change directories to `{JMeter path}/bin/` and run `jmeter.bat`. +- Click *File -> Open (Ctrl+O)* and select `benchmark.jmx` file or drag and drop the `benchmark.jmx` file in the opened GUI. + +In the root node (*Performance Test Plan*) in the left panel, you can change *User Defined Variables* listed in the previous section. +To run a script, click the *Start* button (green arrow in the top menu). + +## Output + +The results of running a JMeter scenario are available in the *View Results Tree* and *Aggregate Report* nodes in the left panel of the JMeter GUI. + +When the script is run via GUI, the results are available in the left panel. Choose the corresponding report. When the script is run via console, a JTL report is generated. You can run JMeter GUI later and open it in the corresponding report node. + +The legacy scenario (Benchmark_2015) contains *View Results Tree*, *Detailed URLs Report* and *Summary Report* nodes. + +### View Results Tree + +This report shows the tree of all requests and responses made during the scenario run. It provides information about the response time, headers and response codes. This report is useful for scenario debugging, but should be disabled during load testing because it consumes a lot of resources. + +You can open a JTL file in this report to debug a scenario and view the requests that cause errors. By default, a JTL file doesn't contain bodies of requests/responses, so it is better to debug scenarios in the GUI mode. + +For more details, read [View Results Tree](http://jmeter.apache.org/usermanual/component_reference.html#View_Results_Tree). + +### Aggregate Report + +This report contains aggregated information about all requests. It provides request count, min, max, average, error rate, approximate throughput, etc. You can open a JTL file in this report to analyze the results of a scenario run. + +For more details, read [Aggregate Report](http://jmeter.apache.org/usermanual/component_reference.html#Aggregate_Report). + +### Detailed URLs Report (Legacy) + +This report contains information about URLs. Note that the URL is displayed only in a generated report file (URL is not displayed in the GUI). The report file name is `{report_save_path}/detailed-urls-report.log`. It can be opened as a CSV file. + +For more details, read [View Results in Table](http://jmeter.apache.org/usermanual/component_reference.html#View_Results_in_Table). + +### Summary Report (Legacy) + +The report contains aggregated information about threads. The report file name is `{report_save_path}/summary-report.log`. + +For more details, read [Summary Report](http://jmeter.apache.org/usermanual/component_reference.html#Summary_Report). + +## Additional Information + +### Threads + +`benchmark.jmx` scenario has the following thread groups and default percentage breakdown: + +- **Frontend Pool** (90%) + +| Thread Group Name | Label Suffix | % of Pool | +| ------------------------- | ------------------------------------------------------ | --------- | +| Catalog Browsing By Guest | Catalog Browsing By Guest | 30 | +| Site Search | SearchQuick, SearchQuickWithFilter and SearchAdvanced | 30 | +| Add To Cart (Guest) | Add To Cart By Guest | 28 | +| Add to Wishlist | WishList | 2 | +| Compare Products | Product Compare By Guest | 2 | +| Checkout By Guest | Checkout By Guest | 4 | +| Checkout By Customer | Checkout By Customer | 4 | + +Site Search thread group contains 3 variations: +- Quick Search (65%) +- Quick Search With Filtering (35%) +- Advanced Search (5%) + +- **Admin Pool** (10%) + +| Thread Group Name | Label Suffix | % of Pool | +| ----------------------------------------- | ------------ | --------- | +| *Merchandizing Pool* (see below) | - | 50 | +| Admin Promotion Rules | - | 10 | +| Admin API - Process Orders | - | 30 | +| Admin Create/Process Returns | - | 10 | + +*Merchandizing Pool* (50% of Admin Pool) + +| Thread Group Name | Label Suffix | % of Pool | +| ----------------------------------------- | ------------ | --------- | +| *Product Management Pool* (see below) | - | 90 | +| Admin Category Management (Merchandizing) | - | 10 | + +*Product Management Pool* (90% of Merchandizing Pool) + +| Thread Group Name | Label Suffix | % of Pool | +| ----------------------------------------- | ------------ | --------- | +| Admin Edit Product (Merchandizing) | - | 60 | +| Admin Create Product (Merchandizing) | - | 40 | + +- **CSR Pool** (0%) + +| Thread Group Name | Label Suffix | % of Pool | +| -------------------------- | ------------ | --------- | +| CSR Browse Customers | - | 10 | +| CSR Create Order | - | 70 | +| CSR Create/Process Returns | - | 20 | + +The number of threads in each group can be calculated by formula: + + N = {numberOfThreads} * {poolPercentage} * {threadGroupPercentage} / 10000 + +For example, the value of {numberOfThreads} parameter is 100 and we want to get the number of threads in the *Checkout By Guest* group: + + N = 100 * 90 * 4 / 10000 = 4 + +The *Merchandizing Pool* and the *Product Management Pool* should be taken into account when the number of product or category management threads needs to be calculated. For example, the number of threads in *Admin Create Product (Merchandizing)* group is calculated as follows: + + N = {numberOfThreads} * {adminPoolPercentage} * {merchandizingPercentage} * {adminProductManagementPercentage} * {adminProductCreationPercentage} / 100 / 100 / 100 / 100 + +If {numberOfThreads} equals to 100: + + N = 100 * 10 * 50 * 90 * 40 / 100000000 = 2 + +To change the percentage breakdown, pass custom values for each pool or thread group to the script. For example, to run the scenario with *Frontend Pool* only enabled, run the script with the following parameters + + -JfrontEndPoolPercentage=100 -JadminPoolPercentage=0 -JcsrPoolPercentage=0. + +**Legacy Threads** + +The `benchmark_2015.jmx` script consists of five thread groups: the setup thread and four user threads. +By default, the percentage ratio between thread groups is as follows: +- Browsing, adding items to the cart and abandon cart (BrowsAddToCart suffix in reports) - 62% +- Just browsing (CatProdBrows suffix in reports) - 30% +- Browsing, adding items to cart and checkout as guest (GuestChkt suffix in reports) - 4% +- Browsing, adding items to cart and checkout as registered customer (CustomerChkt suffix in reports) - 4% + +### Results Interpretation + +In order to build an aggregate report from the results of the `benchmark.kmx` scenario run, use the script `generate-b2c.php` in the folder `setup/performance-toolkit/aggregate-report`. + +The script parses the JTL file and generates an aggregate report in CSV format. The report consists of the 4 sections separated by two empty lines: + +1. Summary information: Checkouts Per Hour, Page Views Per Hour and Test Duration (in seconds) +2. Aggregated information about all requests within each thread group (median time, average time, min/max, amount of hits per hour, etc.) +3. Aggregated information about common requests (open home page, category page, product page, login, etc.) accross the entire scenario +4. List of the requests that weren't executed during the scenario run + +Also, the aggregate report can include information about the memory usage for each request type. This requires additional configuration. You should add the following code at the end of `pub/index.php`: + + if (strpos($_SERVER['REQUEST_URI'], '/banner/ajax/load/') === false) { + if (!file_exists('../var/log/memory_usage.log')) { + file_put_contents('../var/log/memory_usage.log', str_pad('Usage', 12, ' ', STR_PAD_LEFT) . ' ' . str_pad('Real Usage', 12, ' ', STR_PAD_LEFT) . ' URI' . "\n", FILE_APPEND | LOCK_EX); + } + $result = str_pad(memory_get_peak_usage(), 12, ' ', STR_PAD_LEFT) . ' ' . str_pad(memory_get_peak_usage(true), 12, ' ', STR_PAD_LEFT) . ' ' . $_SERVER['REQUEST_URI']; + file_put_contents('../var/log/memory_usage.log', $result . "\n", FILE_APPEND | LOCK_EX); + } +After that, the information about memory usage for each request will be logged in the file `var/log/memory_usage.log`. + +To generate the aggregate report, run the following command from the Magento root directory: + + php setup/performance-toolkit/aggregate-report/generate-b2c.php -j {path to folder with JTL file}/jmeter_report.jtl -m var/log/memory_usage.log -o aggregate_report.csv + +**Legacy Scenario** + +It is convenient to use *Summary Report* for the results analysis. To evaluate the number of each request per hour, use the value in the *Throughput* column. + +To get the summary value of throughput for some action: +1. Find all rows that relate to the desired action +2. Convert values from *Throughput* column to a common denominator +3. Sum up the obtained values + +For example, to get summary throughput for the *Simple Product View* action when the following rows are present in the *Summary Report*: + +| Label | # Samples | ... | Throughput | +| ------------------------------------- | --------------- | --- | ---------- | +| ... | ... | ... | ... | +| Open Home Page(CatProdBrows) | 64 | ... | 2.2/sec | +| Simple Product 1 View(GuestChkt) | 4 | ... | 1.1/sec | +| Simple Product 2 View(BrowsAddToCart) | 30 | ... | 55.6/min | +| ... | ... | ... | ... | + +Find all rows with the label *Simple Product # View* and calculate the summary throughput: + + 1.1/sec + 55.6/min = 66/min + 55.6/min = 121.6/min = 2.02/sec + +If you need information about the summary throughput of the *Checkout* actions, find the rows with labels *Checkout success* and make the same calculation. + +For the total number of page views, sum up all actions, minus the setup thread. diff --git a/setup/performance-toolkit/README.txt b/setup/performance-toolkit/README.txt deleted file mode 100644 index 09c9b57965e5f..0000000000000 --- a/setup/performance-toolkit/README.txt +++ /dev/null @@ -1,91 +0,0 @@ -Performance Toolkit -============= - -Installation ------------ -jMeter: --- go to http://jmeter.apache.org/download_jmeter.cgi and download jMeter in Binary section (pay you attention that Java 6 or later is required) --- unzip archive - -Json Plugins: --- go to https://jmeter-plugins.org/install/Install/ --- download plugins-manager.jar and put it into /lib/ext directory, then restart JMeter --- follow instructions from https://jmeter-plugins.org/wiki/PluginsManager/ to open Plugins Manager --- select Json Plugins in plugins listing from "Available Plugins" tab, then click "Apply changes and restart JMeter" button - - -Usage ------------ -Before running the jMeter tests for the first time, you will need to first use bin/magento setup:performance:generate-fixtures command to generate the test data. - -1. Run via console -Scenario can accept parameters that are described bellow in format : - - URL component 'host' of application being tested (URL or IP). Default is 'localhost'. - Base path for tested site. Default is '/'. - Path where reports will be saved. Reports will be saved in current working directory by default. Default is './'. - Ramp period (seconds). Period the request will be distributed within. Default is '300'. - Number of orders in the period specified in the current allocation. If is specified, the parameter will be recalculated. Default is '0'. - Number of concurrent users. Recommended amount is 100. Minimal amount is 10. Default is '100'. - Percentage of users that will only reach the add to cart stage. Default is '62'. - Percentage of users that will only reach the view catalog stage. Default is '30'. - Percentage of users that will reach the guest checkout stage. Default is '4'. - Percentage of users that will reach the (logged-in) customer checkout stage. Default is '4'. - Number of loops to run. Default is '1'. - Admin backend path. Default is 'admin'. - Admin backend user. Default is 'admin'. - Admin backend password. Default is '123123q'. - Deviation (ms) for "think time" emulation. Default is '1000'. - Constant delay offset (ms) for "think time" emulation. Default is '2000'. - -Necessary parameters must be passed to command line with "J" prefix: "-J=" - -Example: -> cd /directory_of_jMeter/bin/ -> jmeter -n -t /path_to_benchmark_file/benchmark.jmx -Jhost=magento2.dev -Jbase_path=/ -Jusers=100 -Jramp_period=300 -Jreport_save_path=./ - -2. Run via GUI --- Open jMeter/bin directory and run jmeter.bat --- Click in menu File -> Open (Ctrl+O) and select file; or drag and drop benchmark.jmx file in opened GUI. - -On the first tab 'Test Toolkit' you can change 'User Defined variables' like as , , , , . -For running script click "Start" (green arrow in the top menu). - - -Results of running (Report types) ------------ - -After running via GUI you can see result of working in left panel. Choose the corresponding report. -After running script via console report will be generated in the path that has been specified in . - - -Threads ------------ - -jMeter script consists of five threads. Setup thread and four user threads. -Percentage ratio between threads is as follows: -Browsing, adding items to the cart and abandon cart (BrowsAddToCart suffix in reports) - 62% -Just browsing (BrowsAddToCart suffix in reports) - 30% -Browsing, adding items to cart and checkout it as guest (GuestChkt suffix in reports) - 4% -Browsing, adding items to cart and checkout as registered customer (CustomerChkt suffix in reports) - 4% - - -About reports: ------------ - -Summary Report. -Report contains aggregated information about threads. -Report file name is {report_save_path}/summary-report.log -Details http://jmeter.apache.org/usermanual/component_reference.html#Summary_Report - -Detailed URLs report. -Report contains information about URLs. -Pay your attention that URL is displayed only in generated report file (in GUI, URL is not displayed). -Report file name is {report_save_path}/detailed-urls-report.log (can be open as csv format). -Details http://jmeter.apache.org/usermanual/component_reference.html#View_Results_in_Table - -About other types read on -http://jmeter.apache.org/usermanual/component_reference.html - -About fixtures generation -http://devdocs.magento.com/guides/v2.2/config-guide/cli/config-cli-subcommands-perf-data.html diff --git a/setup/performance-toolkit/aggregate-report/b2c_mappings.php b/setup/performance-toolkit/aggregate-report/b2c_mappings.php new file mode 100644 index 0000000000000..5de2acb15b97d --- /dev/null +++ b/setup/performance-toolkit/aggregate-report/b2c_mappings.php @@ -0,0 +1,785 @@ + 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page\(Catalog Browsing', + 'scenario' => 'Catalog Browsing', + ], + [ + 'label' => 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page\(Search', + 'scenario' => 'Search', + ], + [ + 'label' => 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page\(Add To Cart', + 'scenario' => 'Add to Cart', + ], + [ + 'label' => 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Open Home Page', + 'uri' => '^\/$', + 'title' => 'Home Page\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category\(Catalog Browsing', + 'scenario' => 'Catalog Browsing', + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category\(Product Compare', + 'scenario' => 'Compare Products', + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Open Category Page', + 'uri' => '\/category-\d+\.html', + 'title' => 'Open Category\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Open Simple Product Page (Guest)', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^(?:Simple )?Product \d+ View', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Simple Product Page (Customer)', + 'uri' => '\/simple-product-\d+\.html', + 'title' => 'Simple Product View', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Catalog Browsing', + 'scenario' => 'Catalog Browsing', + ], + [ + 'label' => 'Open Product Page', + 'uri' => '\/(?:simple|configurable)-product-\d+\.html', + 'title' => '^Product \d+ View(\s\d)?\(Search', + 'scenario' => 'Search', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product View\(WishList', + 'scenario' => 'WishList', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Product Compare', + 'scenario' => 'Compare Products', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Open Simple Product Page', + 'uri' => '\/simple-product-\d+\.html', + 'title' => '^Simple Product \d+ View\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View\(Catalog Browsing', + 'scenario' => 'Catalog Browsing', + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View\(Product Compare', + 'scenario' => 'Compare Products', + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Open Configurable Product Page', + 'uri' => '\/configurable-product-\d+\.html', + 'title' => 'Configurable Product \d+ View\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Quick Search', + 'uri' => '\/catalogsearch\/result', + 'title' => 'Search\(SearchQuick\)', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Ajax Product Review', + 'uri' => '\/review\/product\/listAjax\/id\/\d+', + 'title' => 'Ajax Review.*\(Search', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Quick Search With Filter', + 'uri' => '\/catalogsearch\/result', + 'title' => 'Search(?:\s\d)?\(SearchQuickWithFilter\)', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Filter By Attribute', + 'uri' => '\/catalogsearch\/result', + 'title' => 'Filter by Attribute', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Open Advanced Search Page', + 'uri' => '\/catalogsearch\/advanced', + 'title' => 'Open Advanced Search', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Perform Advanced Search', + 'uri' => '\/catalogsearch\/advanced\/result', + 'title' => '^Search\(SearchAdvanced\)', + 'scenario' => 'Search', + 'is_storefront' => true, + ], + [ + 'label' => 'Add Simple Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Simple.*Add To Cart', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Add Simple Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Simple.*Add To Cart\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Add Simple Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Simple.*Add To Cart\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Add Simple Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Simple.*Add To Cart\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Add Configurable Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Configurable.*Add To Cart', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Add Configurable Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Configurable.*Add To Cart\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Add Configurable Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Configurable.*Add To Cart\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Add Configurable Product To Cart', + 'uri' => '\/checkout\/cart\/add\/uenc', + 'title' => 'Configurable.*Add To Cart\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Load Customer Cart Section', + 'uri' => '\/customer\/section\/load.*sections=cart', + 'title' => '(Customer Section )?Load\s*(?:Guest|Customer)+', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Load Customer Cart Section', + 'uri' => '\/customer\/section\/load.*sections=cart', + 'title' => 'Load Guest\d?\(Add To Cart', + 'scenario' => 'Add To Cart', + ], + [ + 'label' => 'Load Customer Cart Section', + 'uri' => '\/customer\/section\/load.*sections=cart', + 'title' => 'Load Guest\d?\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + ], + [ + 'label' => 'Load Customer Cart Section', + 'uri' => '\/customer\/section\/load.*sections=cart', + 'title' => 'Load Customer\d?\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Delete Item From Shopping Cart', + 'uri' => '\/checkout\/cart\/delete', + 'title' => 'Delete From Cart', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Login Page', + 'uri' => '\/customer\/account\/login', + 'title' => 'Open Login Page', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Open Login Page', + 'uri' => '\/customer\/account\/login', + 'title' => 'Open Login Page\(WishList', + 'scenario' => 'WishList', + ], + [ + 'label' => 'Open Login Page', + 'uri' => '\/customer\/account\/login', + 'title' => 'Open Login Page\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Ajax Load Login Form', + 'uri' => '\/page_cache\/block\/render', + 'title' => 'Ajax Load Login Form', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Ajax Load Login Form', + 'uri' => '\/page_cache\/block\/render', + 'title' => 'Ajax Load Login Form\(WishList', + 'scenario' => 'WishList', + ], + [ + 'label' => 'Ajax Load Login Form', + 'uri' => '\/page_cache\/block\/render', + 'title' => 'Ajax Load Login Form\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Login Action', + 'uri' => '\/customer\/account\/loginPost', + 'title' => '^Login\s*\(', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Login Action', + 'uri' => '\/customer\/account\/loginPost', + 'title' => 'Login\s*\(WishList', + 'scenario' => 'WishList', + ], + [ + 'label' => 'Login Action', + 'uri' => '\/customer\/account\/loginPost', + 'title' => 'Login\s*\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + ], + [ + 'label' => 'Add Product To Wishlist', + 'uri' => '\/wishlist\/index\/add', + 'title' => 'Add To Wishlist', + 'scenario' => 'Wishlist', + 'is_storefront' => true, + ], + [ + 'label' => 'Load Wishlist Section', + 'uri' => '\/customer\/section\/load.*sections=wishlist', + 'title' => 'Load Wishlist', + 'scenario' => 'Wishlist', + 'is_storefront' => true, + ], + [ + 'label' => 'Delete Item From Wishlist', + 'uri' => 'wishlist\/index\/remove', + 'title' => 'Clear Wishlist', + 'scenario' => 'Wishlist', + 'is_storefront' => true, + ], + [ + 'label' => 'Logout Action', + 'uri' => '\/customer\/account\/logout', + 'title' => 'Logout', + 'is_service_url' => true, + 'is_storefront' => true, + ], + [ + 'label' => 'Add Simple Product To Compare List', + 'uri' => '\/catalog\/product_compare\/add', + 'title' => '^(Simple )?Product .* Comparison Add', + 'scenario' => 'Compare Products', + 'is_storefront' => true, + ], + [ + 'label' => 'Add Configurable Product To Compare List', + 'uri' => '\/catalog\/product_compare\/add', + 'title' => 'Configurable Product .* Comparison Add', + 'scenario' => 'Compare Products', + 'is_storefront' => true, + ], + [ + 'label' => 'Compare Products', + 'uri' => '\/catalog\/product_compare\/index\/items\/', + 'title' => 'Compare Products\(.*', + 'scenario' => 'Compare Products', + 'is_storefront' => true, + ], + [ + 'label' => 'Remove Products From Comparison', + 'uri' => '\/catalog\/product_compare\/clear', + 'title' => 'Compare Products Clear', + 'scenario' => 'Compare Products', + 'is_storefront' => true, + ], + [ + 'label' => 'Start Checkout (Guest)', + 'uri' => '\/checkout\/$', + 'title' => 'Checkout Start\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Check If Email Is Available', + 'uri' => '\/rest\/default\/V1\/customers\/isEmailAvailable', + 'title' => 'Checkout Email Available', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Estimate Shipping Methods (Guest)', + 'uri' => '\/rest\/default\/V1\/guest-carts\/[a-f0-9]+\/estimate-shipping-methods', + 'title' => 'Checkout Estimate Shipping Methods\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Billing/Shipping Information (Guest)', + 'uri' => '\/rest\/default\/V1\/guest-carts\/[a-f0-9]+\/shipping-information', + 'title' => 'Checkout Billing\/Shipping Information\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Payment/Info Place Order (Guest)', + 'uri' => '\/rest\/default\/V1\/guest-carts\/[a-f0-9]+\/payment-information', + 'title' => 'Checkout Payment Info\/Place Order\(Checkout By Guest', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Success Page By Guest', + 'uri' => '\/checkout\/onepage\/success', + 'title' => 'Checkout success\(Checkout By Guest\)', + 'scenario' => 'Checkout By Guest', + 'is_storefront' => true, + ], + [ + 'label' => 'Start Checkout (Customer)', + 'uri' => '\/checkout\/$', + 'title' => 'Checkout Start\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Estimate Shipping Methods (Customer)', + 'uri' => '\/rest\/default\/V1\/carts\/mine\/estimate-shipping-methods-by-address-id', + 'title' => 'Checkout Estimate Shipping Methods\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Billing/Shipping Information (Customer)', + 'uri' => '\/rest\/default\/V1\/carts\/mine\/shipping-information', + 'title' => 'Checkout Billing\/Shipping Information\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Payment/Info Place Order (Customer)', + 'uri' => '\/rest\/default\/V1\/carts\/mine\/payment-information', + 'title' => 'Checkout Payment Info\/Place Order\(Checkout By Customer', + 'scenario' => 'Checkout By Customer', + 'is_storefront' => true, + ], + [ + 'label' => 'Checkout Success Page By Customer', + 'uri' => '\/checkout\/onepage\/success', + 'title' => 'Checkout success\(Checkout By Customer\)', + 'scenario' => 'Checkout By Customer', + 'is_storefront' => true, + ], + [ + 'label' => 'Login To Admin Panel', + 'uri' => '\/admin', + 'title' => '- Login$', + 'is_service_url' => true + ], + [ + 'label' => 'Login To Admin Panel - Submit Form', + 'uri' => '\/admin\/admin\/dashboard', + 'title' => '- Login Submit Form', + 'is_service_url' => true, + ], + [ + 'label' => 'Admin - Edit Simple Product', + 'uri' => '\/admin\/catalog\/product\/edit\/id', + 'title' => 'Admin Edit Product - Edit Simple Product$', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Validate Simple Product', + 'uri' => '\/admin\/catalog\/product\/validate\/id', + 'title' => 'Admin Edit Product - Edit Simple Product Validate', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Save Simple Product', + 'uri' => '\/admin\/catalog\/product\/save\/id', + 'title' => 'Admin Edit Product - Edit Simple Product Save', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Edit Configurable Product', + 'uri' => '\/admin\/catalog\/product\/edit\/id', + 'title' => 'Admin Edit Product - Edit Configurable Product$', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Validate Configurable Product', + 'uri' => '\/admin\/catalog\/product\/validate\/id', + 'title' => 'Admin Edit Product - Edit Configurable Product Validate', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Save Configurable Product', + 'uri' => '\/admin\/catalog\/product\/save\/id', + 'title' => 'Admin Edit Product - Edit Configurable Product Save', + 'scenario' => 'Admin - Edit Product', + ], + [ + 'label' => 'Admin - Open Product Page', + 'uri' => '\/admin\/catalog\/product\/', + 'title' => 'Admin Create Product - Catalog Product', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Create New Bundle Product', + 'uri' => '\/admin\/catalog\/product\/new\/set\/4\/type\/bundle\/', + 'title' => 'Admin Create Product - New Bundle Product$', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Validate New Bundle Product', + 'uri' => '\/admin\/catalog\/product\/validate\/set\/4\/', + 'title' => 'Admin Create Product - New Bundle Product Validate', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Save New Bundle Product', + 'uri' => '\/admin\/catalog\/product\/save\/set\/4\/type\/bundle\/back\/edit\/active_tab\/product-details\/', + 'title' => 'Admin Create Product - New Bundle Product Save', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Create New Configurable Product', + 'uri' => '\/admin\/catalog\/product\/new\/set\/4\/type\/configurable\/', + 'title' => 'Admin Create Product - New Configurable Product$', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Create Product Options', + 'uri' => '\/admin\/catalog\/product_attribute\/createOptions\/\?isAjax=true', + 'title' => 'Admin Create Product - Create Options', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Validate New Configurable Product', + 'uri' => '\/admin\/catalog\/product\/validate\/set\/4\/', + 'title' => 'Admin Create Product - New Configurable Product Validate', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Save New Configurable Product', + 'uri' => '\/admin\/catalog\/product\/save\/set\/4\/type\/configurable' + . '\/back\/edit\/active_tab\/product-details\/', + 'title' => 'Admin Create Product - New Configurable Product Save', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Create New Downloadable Product', + 'uri' => '\/admin\/catalog\/product\/new\/set\/4\/type\/downloadable\/', + 'title' => 'Admin Create Product - New Downloadable Product$', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Add Original File To Downloadable Product', + 'uri' => '\/admin\/downloadable_file\/upload\/type\/links\/\?isAjax=true', + 'title' => 'Admin Create Product - New Downloadable Upload Original File', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Add Sample File To Downloadable Product', + 'uri' => '\/admin\/downloadable_file\/upload\/type\/samples\/\?isAjax=true', + 'title' => 'Admin Create Product - New Downloadable Upload Sample File', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Validate New Downloadable Product', + 'uri' => '\/admin\/catalog\/product\/validate\/set\/4\/type\/downloadable\/', + 'title' => 'Admin Create Product - New Downloadable Product Validate', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Save New Downloadable Product', + 'uri' => '\/admin\/catalog\/product\/save\/set\/4\/type\/downloadable' + . '\/back\/edit\/active_tab\/product-details\/', + 'title' => 'Admin Create Product - New Downloadable Product Save', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Create New Simple Product', + 'uri' => '\/admin\/catalog\/product\/new\/set\/4\/type\/simple\/', + 'title' => 'Admin Create Product - New Simple Product$', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Validate New Simple Product', + 'uri' => '\/admin\/catalog\/product\/validate\/set\/4\/', + 'title' => 'Admin Create Product - New Simple Product Validate', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Save New Simple Product', + 'uri' => '\/admin\/catalog\/product\/save\/set\/4\/type\/simple\/back\/edit\/active_tab\/product-details\/', + 'title' => 'Admin Create Product - New Simple Product Save', + 'scenario' => 'Admin - Create Product', + ], + [ + 'label' => 'Admin - Open Category', + 'uri' => '\/admin\/catalog\/category\/', + 'title' => 'Admin Category Management - Landing Page', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Edit Category', + 'uri' => '\/admin\/catalog\/category\/edit\/id\/', + 'title' => 'Admin Category Management - Select parent category', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Open New Category Page', + 'uri' => '\/admin\/catalog\/category\/add\/store\/0\/parent\/', + 'title' => 'Admin Category Management - Open new category page', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Create Empty Category', + 'uri' => '\/admin\/catalog\/category\/save\/', + 'title' => 'Admin Category Management - Create empty category', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Add Products To Category', + 'uri' => '\/admin\/merchandiser\/position\/save\/', + 'title' => 'Admin Category Management - Add products', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Verify Products Added To Category', + 'uri' => '\/admin\/merchandiser\/category\/grid\/id\/', + 'title' => 'Admin Category Management - Verify products added', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Save Category With Products', + 'uri' => '\/admin\/catalog\/category\/save\/', + 'title' => 'Admin Category Management - Save category', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Move Category', + 'uri' => '\/admin\/catalog\/category\/move\/', + 'title' => 'Admin Category Management - Move category', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Delete Category', + 'uri' => '\/admin\/catalog\/category\/delete\/id\/', + 'title' => 'Admin Category Management - Delete category', + 'scenario' => 'Admin - Category Management', + ], + [ + 'label' => 'Admin - Open Promotions Page', + 'uri' => '\/admin\/sales_rule\/promo_quote\/$', + 'title' => 'Admin Promotions Management - Landing Page', + 'scenario' => 'Admin - Promotion Rules', + ], + [ + 'label' => 'Admin - Create New Promotion Rule', + 'uri' => '\/admin\/sales_rule\/promo_quote\/new$', + 'title' => 'Admin Promotions Management - Create New$', + 'scenario' => 'Admin - Promotion Rules', + ], + [ + 'label' => 'Admin - Create New Condition For Promotion Rule', + 'uri' => '\/admin\/sales_rule\/promo_quote\/newConditionHtml\/form\/sales_rule_formrule_conditions_fieldset_' + . '\/form_namespace\/sales_rule_form', + 'title' => 'Admin Promotions Management - Create New Conditional', + 'scenario' => 'Admin - Promotion Rules', + ], + [ + 'label' => 'Admin - Save Promotion Rule', + 'uri' => '\/admin\/sales_rule\/promo_quote\/save\/', + 'title' => 'Admin Promotions Management - Save$', + 'scenario' => 'Admin - Promotion Rules', + ], + [ + 'label' => 'API - Create Invoice', + 'uri' => '\/rest\/default\/V1\/order\/\d+\/invoice', + 'title' => 'API - Create Invoice', + 'scenario' => 'Admin - Process Orders', + ], + [ + 'label' => 'API - Create Shipment', + 'uri' => '\/rest\/default\/V1\/order\/\d+\/ship', + 'title' => 'API - Create Shipment', + 'scenario' => 'Admin - Process Orders', + ], + [ + 'label' => 'Admin - Open Orders Grid', + 'uri' => '\/admin\/mui\/index\/render', + 'title' => 'Admin Edit Order - Open Orders', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Open Orders Grid With Filter', + 'uri' => '\/admin\/mui\/index\/render', + 'title' => 'Admin Edit Order - Search Pending Orders Limit', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Open Orders Page', + 'uri' => '\/admin\/sales\/order\/', + 'title' => 'Admin Edit Order - Orders Page', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Open Order', + 'uri' => '\/admin\/sales\/order\/view\/order_id\/', + 'title' => 'Admin Edit Order - Open Order$', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Start Invoicing', + 'uri' => '\/admin\/sales\/order_invoice\/start\/order_id\/', + 'title' => 'Admin Edit Order - Invoice Start', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Submit Invoice', + 'uri' => '\/admin\/sales\/order_invoice\/save\/order_id\/', + 'title' => 'Admin Edit Order - Invoice Submit', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Start Credit Memo', + 'uri' => '\/admin\/sales\/order_creditmemo\/start\/order_id\/', + 'title' => 'Admin Edit Order - Credit Memo Start', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Submit Credit Memo', + 'uri' => '\/admin\/sales\/order_creditmemo\/save\/order_id\/', + 'title' => 'Admin Edit Order - Credit Memo Submit', + 'scenario' => 'Admin - Create/Process Returns', + ], + [ + 'label' => 'Admin - Search Order By Increment Id', + 'uri' => '\/admin\/mui\/index\/render', + 'title' => 'Admin Edit Order - Search Orders$', + 'scenario' => 'Admin - Create/Process Returns', + ], +]; diff --git a/setup/performance-toolkit/aggregate-report/common.php b/setup/performance-toolkit/aggregate-report/common.php new file mode 100644 index 0000000000000..ae332ecbf9e70 --- /dev/null +++ b/setup/performance-toolkit/aggregate-report/common.php @@ -0,0 +1,312 @@ + $line[0], + 'uri' => $line[2], + ]; + } + fclose($file); + + return $memoryUsage; +} + +/** + * Parse JTL report and group all http requests by title. + * + * @param string $jmeterReport Path to the JTL report + * @param bool $includeErrors If true failed requests are included in report + * @return array First element - requests grouped by title, second - total execution time of the scenario + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ +function parseJmeterReport($jmeterReport, $includeErrors) +{ + $result = []; + $f = fopen($jmeterReport, 'r'); + $line = fgetcsv($f); + if (is_array($line) && count($line) > 1) { + $delimiter_char = ","; + } elseif (is_array($line = fgetcsv($f, 1000, $delimiter = "|")) && count($line) > 1) { + $delimiter_char = "|"; + } + do { + $responseTime = (int)$line[1]; + if (is_numeric($responseTime)) { + $title = $line[2]; + if (!$includeErrors) { + if ($line[7] == 'false') { + continue; + } + } + if (!isset($result[$title])) { + $result[$title] = ['times' => []]; + } + $result[$title]['times'][] = $responseTime; + + if (strpos($title, 'WarmUp Add To Cart') !== false) { + $startTime = $line[0]; + } + if (strpos($title, 'Clear properties') !== false) { + $endTime = $line[0]; + } + } + } while (!feof($f) && is_array($line = fgetcsv($f, 1000, $delimiter = $delimiter_char))); + + return [$result, $endTime - $startTime]; +} + +/** + * Aggregate data from JTL and memory log using mapping. + * + * @param array $jmeterData + * @param array $memoryUsageData + * @param array $mappings + * @return array + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ +function prepareAggregatedResult(array $jmeterData, array $memoryUsageData, array $mappings) +{ + $aggregatedResult = []; + foreach ($mappings as $key => $mapping) { + $aggregatedResult[$key]['label'] = $mapping['label']; + $aggregatedResult[$key]['scenario'] = $mapping['scenario'] ?? 'Total'; + $aggregatedResult[$key]['is_service_url'] = $mapping['is_service_url'] ?? false; + $aggregatedResult[$key]['is_requisition'] = $mapping['is_requisition'] ?? false; + $aggregatedResult[$key]['is_storefront'] = $mapping['is_storefront'] ?? false; + $aggregatedResult[$key]['time'] = []; + $aggregatedResult[$key]['labels'] = []; + $aggregatedResult[$key]['order'] = 0; + $order = 0; + foreach ($jmeterData as $label => $time) { + $order++; + if (strpos($label, 'SetUp') !== false && !$aggregatedResult[$key]['is_service_url']) { + continue; + } + if (preg_match('/' . $mapping['title'] . '/i', $label)) { + if (empty($aggregatedResult[$key]['order'])) { + $aggregatedResult[$key]['order'] = $order; + } + array_push($aggregatedResult[$key]['time'], ...$time['times']); + if (!in_array($label, $aggregatedResult[$key]['labels']) + && !$aggregatedResult[$key]['is_service_url']) { + array_push($aggregatedResult[$key]['labels'], $label); + } + } + } + $memoryUsage = []; + foreach ($memoryUsageData as $row) { + if (preg_match('/' . $mapping['uri'] . '/i', $row['uri'])) { + $memoryUsage[] = $row['memory']; + } + } + $aggregatedResult[$key]['memory'] = count($memoryUsage) + ? round(calculate_average($memoryUsage) / 1024 / 1024, 2) : '-'; + } + usort( + $aggregatedResult, + function ($a, $b) { + return $a['order'] <=> $b['order']; + } + ); + return $aggregatedResult; +} + +/** + * Write aggregate report to the output file. + * + * @param array $aggregatedResult + * @param int $executionTime + * @param string $outputFile Path to the output report + * @param callable $generateSummary + * @param callable $rowCallback [optional] + * @return void + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ +function parseReportAndWriteToCsv( + array $aggregatedResult, + $executionTime, + $outputFile, + callable $generateSummary, + callable $rowCallback = null +) { + $headersArray = [ + 'Scenario', + 'Label', + 'JMeter Label', + 'Median elapsed time, ms', + 'Average elapsed time, ms', + 'Min elapsed time, ms', + 'Max elapsed time, ms', + '95 percentile elapsed time, ms', + '99 percentile elapsed time, ms', + 'Amount of hits per hour', + 'Memory Usage, Mb' + ]; + $fp = fopen($outputFile, 'w'); + $generateSummary($fp, $aggregatedResult, $headersArray, $executionTime); + foreach ($aggregatedResult as $row) { + if (count($row['time']) && !$row['is_service_url']) { + sort($row['time']); + $ar = [ + $row['scenario'], + $row['label'], + implode("\n", $row['labels']), + calculate_median($row['time']), + calculate_average($row['time']), + min($row['time']), + max($row['time']), + calculate_percentile($row['time'], 0.95), + calculate_percentile($row['time'], 0.99), + round(count($row['time']) / $executionTime * 3600000, 2), + $row['memory'] + ]; + if ($rowCallback) { + $rowCallback($row, $ar); + } + fputcsv($fp, $ar); + } + } + fputcsv($fp, ['']); + fputcsv($fp, ['']); + foreach ($aggregatedResult as $row) { + if (count($row['time']) && $row['is_service_url']) { + sort($row['time']); + $ar = [ + 'Total', + $row['label'], + implode("\n", $row['labels']), + calculate_median($row['time']), + calculate_average($row['time']), + min($row['time']), + max($row['time']), + calculate_percentile($row['time'], 0.95), + calculate_percentile($row['time'], 0.99), + round(count($row['time']) / $executionTime * 3600000, 2), + $row['memory'] + ]; + if ($rowCallback) { + $rowCallback($row, $ar); + } + fputcsv($fp, $ar); + } + } + fputcsv($fp, ['']); + fputcsv($fp, ['']); + foreach ($aggregatedResult as $row) { + if (count($row['time']) == 0) { + $ar = [$row['scenario'], $row['label'], '-', '-', '-', '-', '-', '-', '-', 0, '-']; + if ($rowCallback) { + $rowCallback($row, $ar); + } + fputcsv($fp, $ar); + } + } + fclose($fp); +} + +/** + * Calculate average value of elements in array. + * + * @param array $arr + * @return int + */ +function calculate_average(array $arr) +{ + return (int)(array_sum($arr)/count($arr)); +} + +/** + * Calculate median value of elements in array. + * + * @param array $arr + * @return int + */ +function calculate_median(array $arr) +{ + $count = count($arr); + $middleval = floor(($count - 1) / 2); + if ($count % 2) { + $median = $arr[$middleval]; + } else { + $low = $arr[$middleval]; + $high = $arr[$middleval+1]; + $median = (($low + $high) / 2); + } + return (int)$median; +} + +/** + * Calculate percentile value of elements in array. + * + * @param array $arr + * @param float $percentile From 0 to 1 + * @return int + */ +function calculate_percentile(array $arr, $percentile) +{ + $count = count($arr); + $allindex = ($count - 1) * $percentile; + $intvalindex = intval($allindex); + $floatval = $allindex - $intvalindex; + if (!is_float($floatval)) { + $result = $arr[$intvalindex]; + } else { + if ($count > $intvalindex + 1) { + $result = $floatval * ($arr[$intvalindex + 1] - $arr[$intvalindex]) + $arr[$intvalindex]; + } else { + $result = $arr[$intvalindex]; + } + } + return (int)$result; +} diff --git a/setup/performance-toolkit/aggregate-report/generate-b2c.php b/setup/performance-toolkit/aggregate-report/generate-b2c.php new file mode 100644 index 0000000000000..2fa9339f35b7e --- /dev/null +++ b/setup/performance-toolkit/aggregate-report/generate-b2c.php @@ -0,0 +1,30 @@ + + + request_protocol + ${__P(request_protocol,http)} + = + abandonedCartByGuest ${__P(abandonedCartByGuest,0)} @@ -389,6 +394,11 @@ ${__P(catalogBrowsingByCustomerPercent,100)} = + + categories_count + ${__P(categories_count,100)} + = + checkoutByGuest ${__P(checkoutByGuest,0)} @@ -409,6 +419,11 @@ ${__P(checkoutByCustomerPercent,100)} = + + configurable_products_count + ${__P(configurable_products_count,30)} + = + customer_checkout_percent ${__P(customer_checkout_percent,4)} @@ -539,6 +554,11 @@ ${__P(scenario,)} = + + seedForRandom + ${__P(seedForRandom,1)} + = + searchQuick ${__P(searchQuick,0)} @@ -574,6 +594,11 @@ ${__P(setupAndTearDownThread,1)} = + + simple_products_count + ${__P(simple_products_count,30)} + = + sprint_identifier ${__P(sprint_identifier,)} @@ -656,7 +681,7 @@ - http + ${request_protocol} utf-8 Java @@ -717,8 +742,17 @@ - - props.remove("category_url_key"); + + +// Init and save random object for get random values with/without seed +import java.util.Random; +Random random = new Random(); +if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom}); +} +props.put("RandomObject", random); + +props.remove("category_url_key"); props.remove("category_url_keys_list"); props.remove("category_name"); props.remove("category_names_list"); @@ -770,7 +804,7 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr - + ${request_protocol} ${base_path}${admin_path} GET @@ -850,7 +884,7 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr - + ${request_protocol} ${base_path}${admin_path}/admin/dashboard/ POST @@ -904,7 +938,7 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr - + ${request_protocol} ${base_path}${admin_path}/admin/cache/massEnable POST @@ -947,7 +981,7 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr - + ${request_protocol} ${base_path}${admin_path}/admin/cache/massRefresh POST @@ -960,56 +994,159 @@ if (!slash.equals(path.substring(path.length() -1)) || !slash.equals(path.substr Refresh all cache types - - - - - - - - - - - ${base_path} - GET - true - false - true - false - false - - Site - Get Category 1 - + - - - <span>Category ([0-9]+)</span> + + + + Content-Type + application/json + + + Accept + */* + - Assertion.response_data - false - 2 - + - - false - category_url_keys - <a href="http://${host}${base_path}(index.php/)?([^'"]+)${url_suffix}" class="level-top" > - $2$ - - -1 - simple_product_1_url_key - - - - false - category_names - <a href="http://${host}${base_path}(index.php/)?category-([0-9]+)${url_suffix}" class="level-top" ><span>([^'"]+)</span> - $3$ - - -1 - simple_product_1_url_key - + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + Authorization + Bearer ${admin_token} + + + + + + + + true + path + = + true + searchCriteria[filterGroups][0][filters][0][field] + + + true + 1/2/% + = + true + searchCriteria[filterGroups][0][filters][0][value] + + + true + like + = + true + searchCriteria[filterGroups][0][filters][0][conditionType] + + + true + level + = + true + searchCriteria[filterGroups][1][filters][0][field] + + + true + 2 + = + true + searchCriteria[filterGroups][1][filters][0][value] + + + true + ${categories_count} + = + true + searchCriteria[pageSize] + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/categories/list + GET + true + false + false + false + false + + + + + false + category_url_keys + url_key\",\"value\":\"(.*?)\" + $1$ + + -1 + + + + false + category_names + name\":\"(.*?)\" + $1$ + + -1 + + + category_url_keys @@ -1086,63 +1223,40 @@ props.put("category_name", vars.get("category_name")); false - - - - - - - - - - - ${base_path}catalogsearch/result/?limit=30&q=Simple - GET - true - false - true - false - false - - + - - - (?i)Search results for: (.+?)Simple(.+?) + + + + Content-Type + application/json + + + Accept + */* + - Assertion.response_data - false - 2 - - - - false - simple_products_url_keys - <a class="product-item-link"(?s).+?href="http://${host}${base_path}(index.php/)?([^'"]+)${url_suffix}">(?s).+?Simple - $2$ - - -1 - + - - - simple_products_url_keys - simple_products_url_key - true - - - - - + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + - + ${request_protocol} - ${base_path}${simple_products_url_key}${url_suffix} - GET + ${base_path}rest/V1/integration/admin/token + POST true false true @@ -1151,79 +1265,112 @@ props.put("category_name", vars.get("category_name")); - - - simple_product_id - .//input[@type="hidden" and @name="product"]/@value - false - true - false - - - - - simple_product_title - .//*[@data-ui-id='page-title-wrapper']/text() - false - true - false - - - - false - simple_product_uenc - "uenc":"([^"]+)" - $1$ - - 1 - simple_product_1_url_key - + + admin_token + $ + + + BODY + - + - ^\d+$ + ^[a-z0-9-]+$ Assertion.response_data false 1 variable - simple_product_id + admin_token - - - ^.+$ + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + true + type_id + = + true + searchCriteria[filterGroups][0][filters][0][field] + + + true + simple + = + true + searchCriteria[filterGroups][0][filters][0][value] + + + true + ${simple_products_count} + = + true + searchCriteria[pageSize] + - Assertion.response_data - false - 1 - variable - simple_product_title - + + + + + + ${request_protocol} + + ${base_path}rest/V1/products + GET + true + false + true + false + false + + + + + false + simple_products_url_keys + url_key\",\"value\":\"(.*?)\" + $1$ + + -1 + - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - simple_products_url_key - + + false + simple_product_ids + \"id\":(\d+), + $1$ + + -1 + - - - ^.+$ - - Assertion.response_data - false - 1 - variable - simple_product_uenc - + + false + simple_product_names + name\":\"(.*?)\" + $1$ + + -1 + + + + simple_product_ids + simple_product_id + true + + 1 @@ -1236,6 +1383,7 @@ props.put("category_name", vars.get("category_name")); import java.util.ArrayList; import java.util.HashMap; +import org.apache.commons.codec.binary.Base64; // If it is first iteration of cycle then recreate productList if (1 == Integer.parseInt(vars.get("simple_products_counter"))) { @@ -1244,13 +1392,14 @@ if (1 == Integer.parseInt(vars.get("simple_products_counter"))) { } else { productList = props.get("simple_products_list"); } - +String productUrl = vars.get("request_protocol") + "://" + vars.get("host") + vars.get("base_path") + vars.get("simple_products_url_keys_" + vars.get("simple_products_counter"))+ vars.get("url_suffix"); +encodedUrl = Base64.encodeBase64(productUrl.getBytes()); // Create product map Map productMap = new HashMap(); productMap.put("id", vars.get("simple_product_id")); -productMap.put("title", vars.get("simple_product_title")); -productMap.put("url_key", vars.get("simple_products_url_key")); -productMap.put("uenc", vars.get("simple_product_uenc")); +productMap.put("title", vars.get("simple_product_names_" + vars.get("simple_products_counter"))); +productMap.put("url_key", vars.get("simple_products_url_keys_" + vars.get("simple_products_counter"))); +productMap.put("uenc", new String(encodedUrl)); // Collect products map in products list productList.add(productMap); @@ -1260,64 +1409,40 @@ productList.add(productMap); - - - - - - - - - - - ${base_path}catalogsearch/result/?limit=30&q=Configurable - GET - true - false - true - false - false - - + - - - Search results for: (.+?)Configurable(.+?) - <div class="search results"> + + + + Content-Type + application/json + + + Accept + */* + - Assertion.response_data - false - 2 - - - - false - configurable_products_url_keys - <a class="product-item-link"(?s).+?href="http://${host}${base_path}(index.php/)?([^'"]+)${url_suffix}">(?s).+?Configurable - $2$ - - -1 - + - - - configurable_products_url_keys - configurable_products_url_key - true - - - - - + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + - + ${request_protocol} - ${base_path}${configurable_products_url_key}${url_suffix} - GET + ${base_path}rest/V1/integration/admin/token + POST true false true @@ -1326,119 +1451,121 @@ productList.add(productMap); - - - configurable_product_id - .//input[@type="hidden" and @name="product"]/@value - false - true - false - + + admin_token + $ + + + BODY + - - - configurable_product_title - .//*[@data-ui-id='page-title-wrapper']/text() - false - true - false - + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + - + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + true + type_id + = + true + searchCriteria[filterGroups][0][filters][0][field] + + + true + configurable + = + true + searchCriteria[filterGroups][0][filters][0][value] + + + true + ${configurable_products_count} + = + true + searchCriteria[pageSize] + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/products + GET + true + false + true + false + false + + + + false - configurable_product_uenc - "uenc":"([^"]+)" + configurable_products_url_keys + url_key\",\"value\":\"(.*?)\" $1$ - 1 - simple_product_1_url_key + -1 - + false - configurable_product_attribute_id - "[sp|json]+Config": \{"attributes":\{"(\d+)" + configurable_product_ids + \"id\":(\d+), $1$ - 1 + -1 - + false - configurable_product_attribute_option_id - "options":\[\{"id":"(\d+)" + configurable_product_names + name\":\"(.*?)\" $1$ - 1 + -1 - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - configurable_product_id - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - configurable_product_title - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - configurable_products_url_key - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - configurable_product_attribute_id - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - configurable_product_attribute_option_id - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - configurable_product_uenc - + + false + configurable_product_skus + sku\":\"(.*?)\" + $1$ + + -1 + + + + configurable_product_ids + configurable_product_id + true + + 1 @@ -1451,6 +1578,7 @@ productList.add(productMap); import java.util.ArrayList; import java.util.HashMap; +import org.apache.commons.codec.binary.Base64; // If it is first iteration of cycle then recreate productList if (1 == Integer.parseInt(vars.get("configurable_products_counter"))) { @@ -1460,17 +1588,18 @@ if (1 == Integer.parseInt(vars.get("configurable_products_counter"))) { productList = props.get("configurable_products_list"); } +String productUrl = vars.get("request_protocol") + "://" + vars.get("host") + vars.get("base_path") + vars.get("configurable_products_url_keys_" + vars.get("configurable_products_counter"))+ vars.get("url_suffix"); +encodedUrl = Base64.encodeBase64(productUrl.getBytes()); // Create product map Map productMap = new HashMap(); productMap.put("id", vars.get("configurable_product_id")); -productMap.put("title", vars.get("configurable_product_title")); -productMap.put("url_key", vars.get("configurable_products_url_key")); -productMap.put("uenc", vars.get("configurable_product_uenc")); -productMap.put("attribute_id", vars.get("configurable_product_attribute_id")); -productMap.put("attribute_option_id", vars.get("configurable_product_attribute_option_id")); +productMap.put("title", vars.get("configurable_product_names_" + vars.get("configurable_products_counter"))); +productMap.put("sku", vars.get("configurable_product_skus_" + vars.get("configurable_products_counter"))); +productMap.put("url_key", vars.get("configurable_products_url_keys_" + vars.get("configurable_products_counter"))); +productMap.put("uenc", new String(encodedUrl)); // Collect products map in products list -productList.add(productMap); +productList.add(productMap); false @@ -1485,7 +1614,7 @@ productList.add(productMap); - + ${request_protocol} ${base_path}${admin_path}/customer/index/ GET @@ -1585,7 +1714,7 @@ manager.add(cookie); - + ${request_protocol} ${base_path}${admin_path}/mui/index/render/ GET @@ -1778,7 +1907,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}${admin_path}/admin/cache/massDisable POST @@ -1814,7 +1943,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}${admin_path}/admin/cache/ GET @@ -1872,7 +2001,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}${admin_path}/admin/cache/ GET @@ -1930,7 +2059,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}${admin_path}/admin/cache/ GET @@ -2010,7 +2139,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}page_cache/block/render/ GET @@ -2091,7 +2220,7 @@ if ("${cache_indicator}" == "1") { - + ${request_protocol} ${base_path}checkout/cart/add POST @@ -2120,57 +2249,28 @@ if ("${cache_indicator}" == "1") { - - rv1 - '.' - 1 - 999999 - 1 - true - - - - - rv2 - '.' - 1 - 999999 - 2 - true - - - - - rv3 - '.' - 1 - 999999 - 3 - true - - - Passing arguments between threads - number = (int)(${rv1} * props.get("simple_products_list").size()); + +number = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number); vars.put("simple_product_1_url_key", simpleList.get("url_key")); vars.put("simple_product_1_name", simpleList.get("title")); vars.put("simple_product_1_id", simpleList.get("id")); -number1 = (int)(${rv2} * props.get("simple_products_list").size()); +number1 = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number1); vars.put("simple_product_2_url_key", simpleList.get("url_key")); vars.put("simple_product_2_name", simpleList.get("title")); vars.put("simple_product_2_id", simpleList.get("id")); -number = (int)(${rv3} * props.get("configurable_products_list").size()); +number = props.get("RandomObject").nextInt(props.get("configurable_products_list").size()); configurableList = props.get("configurable_products_list").get(number); vars.put("configurable_product_1_url_key", configurableList.get("url_key")); vars.put("configurable_product_1_name", configurableList.get("title")); vars.put("configurable_product_1_id", configurableList.get("id")); -number = (int)(Math.random() * props.get("category_url_keys_list").size()); +number = props.get("RandomObject").nextInt(props.get("category_url_keys_list").size()); vars.put("category_url_key", props.get("category_url_keys_list").get(number)); vars.put("category_name", props.get("category_names_list").get(number)); vars.put("testLabel", "CatProdBrows"); @@ -2188,7 +2288,7 @@ vars.put("testLabel", "CatProdBrows"); - + ${request_protocol} ${base_path} GET @@ -2225,7 +2325,7 @@ vars.put("testLabel", "CatProdBrows"); - + ${request_protocol} ${base_path}${category_url_key}${url_suffix} GET @@ -2283,7 +2383,7 @@ vars.put("testLabel", "CatProdBrows"); - + ${request_protocol} ${base_path}${simple_product_1_url_key}${url_suffix} GET @@ -2297,23 +2397,124 @@ vars.put("testLabel", "CatProdBrows"); - <title>${simple_product_1_name} - <span>In stock</span> + <title>${simple_product_1_name} + <span>In stock</span> + + Assertion.response_data + false + 2 + + + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + + + + + ${think_time_delay_offset} + ${think_time_deviation} + + + + + + + + + + + + ${request_protocol} + + ${base_path}${simple_product_2_url_key}${url_suffix} + GET + true + false + true + false + false + + + + + + <title>${simple_product_2_name} + <span>In stock</span> + + Assertion.response_data + false + 2 + + + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ Assertion.response_data false - 2 + 1 + variable + product_id - - - ${think_time_delay_offset} - ${think_time_deviation} - - - - + @@ -2321,9 +2522,9 @@ vars.put("testLabel", "CatProdBrows"); - + ${request_protocol} - ${base_path}${simple_product_2_url_key}${url_suffix} + ${base_path}review/product/listAjax/id/${product_id}/ GET true false @@ -2335,10 +2536,9 @@ vars.put("testLabel", "CatProdBrows"); - <title>${simple_product_2_name} - <span>In stock</span> + 200 - Assertion.response_data + Assertion.response_code false 2 @@ -2359,7 +2559,7 @@ vars.put("testLabel", "CatProdBrows"); - + ${request_protocol} ${base_path}${configurable_product_1_url_key}${url_suffix} GET @@ -2399,53 +2599,23 @@ vars.put("testLabel", "CatProdBrows"); - - rv1 - '.' - 1 - 999999 - 1 - true - - - - - rv2 - '.' - 1 - 999999 - 2 - true - - - - - rv3 - '.' - 1 - 999999 - 3 - true - - - Passing arguments between threads - number = (int)(${rv1} * props.get("simple_products_list").size()); + number = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number); vars.put("simple_product_1_url_key", simpleList.get("url_key")); vars.put("simple_product_1_name", simpleList.get("title")); vars.put("simple_product_1_id", simpleList.get("id")); vars.put("simple_product_1_uenc", simpleList.get("uenc")); -number1 = (int)(${rv2} * props.get("simple_products_list").size()); +number1 = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number1); vars.put("simple_product_2_url_key", simpleList.get("url_key")); vars.put("simple_product_2_name", simpleList.get("title")); vars.put("simple_product_2_id", simpleList.get("id")); vars.put("simple_product_2_uenc", simpleList.get("uenc")); -number = (int)(${rv3} * props.get("configurable_products_list").size()); +number = props.get("RandomObject").nextInt(props.get("configurable_products_list").size()); configurableList = props.get("configurable_products_list").get(number); vars.put("configurable_product_1_url_key", configurableList.get("url_key")); vars.put("configurable_product_1_name", configurableList.get("title")); @@ -2454,7 +2624,7 @@ vars.put("configurable_attribute_id", configurableList.get("attribute_id")); vars.put("configurable_option_id", configurableList.get("attribute_option_id")); vars.put("configurable_product_1_uenc", simpleList.get("uenc")); -number = (int)(Math.random() * props.get("category_url_keys_list").size()); +number = props.get("RandomObject").nextInt(props.get("category_url_keys_list").size()); vars.put("category_url_key", props.get("category_url_keys_list").get(number)); vars.put("category_name", props.get("category_names_list").get(number)); vars.put("testLabel", "BrowsAddToCart"); @@ -2473,7 +2643,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path} GET @@ -2540,7 +2710,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}page_cache/block/render/ GET @@ -2599,7 +2769,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${category_url_key}${url_suffix} GET @@ -2657,7 +2827,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${simple_product_1_url_key}${url_suffix} GET @@ -2679,6 +2849,56 @@ vars.put("loadType", "Guest"); 2 + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + @@ -2724,7 +2944,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -2778,7 +2998,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -2843,7 +3063,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${simple_product_2_url_key}${url_suffix} GET @@ -2865,6 +3085,56 @@ vars.put("loadType", "Guest"); 2 + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + @@ -2910,7 +3180,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -2966,7 +3236,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -3031,7 +3301,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${configurable_product_1_url_key}${url_suffix} GET @@ -3053,7 +3323,17 @@ vars.put("loadType", "Guest"); 2 - + + + false + configurable_product_sku + itemprop="sku">([^<]*)<\/ + $1$ + NOT_FOUND + 1 + + + ${think_time_delay_offset} @@ -3061,6 +3341,119 @@ vars.put("loadType", "Guest"); + + true + 1 + + + + + + Content-Type + application/json + + + Accept + */* + + + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/configurable-products/${configurable_product_sku}/options/all + GET + true + false + true + false + false + + + + + attribute_ids + $.[*].attribute_id + NO_VALUE + + BODY + + + + option_values + $.[*].values[0].value_index + NO_VALUE + + BODY + + + + + @@ -3105,7 +3498,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -3126,7 +3519,37 @@ vars.put("loadType", "Guest"); - + + + false + + + + try { + attribute_ids = vars.get("attribute_ids"); + option_values = vars.get("option_values"); + attribute_ids = attribute_ids.replace("[","").replace("]","").replace("\"", ""); + option_values = option_values.replace("[","").replace("]","").replace("\"", ""); + attribute_ids_array = attribute_ids.split(","); + option_values_array = option_values.split(","); + args = ctx.getCurrentSampler().getArguments(); + it = args.iterator(); + while (it.hasNext()) { + argument = it.next(); + if (argument.getStringValue().contains("${")) { + args.removeArgument(argument.getName()); + } + } + for (int i = 0; i < attribute_ids_array.length; i++) { + ctx.getCurrentSampler().addArgument("super_attribute[" + attribute_ids_array[i] + "]", option_values_array[i]); + } + } catch (Exception e) { + log.error("eror…", e); + } + + + + @@ -3161,7 +3584,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -3228,53 +3651,24 @@ vars.put("loadType", "Guest"); - - rv1 - '.' - 1 - 999999 - 1 - true - - - - - rv2 - '.' - 1 - 999999 - 2 - true - - - - - rv3 - '.' - 1 - 999999 - 3 - true - - - Passing arguments between threads - number = (int)(${rv1} * props.get("simple_products_list").size()); + +number = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number); vars.put("simple_product_1_url_key", simpleList.get("url_key")); vars.put("simple_product_1_name", simpleList.get("title")); vars.put("simple_product_1_id", simpleList.get("id")); vars.put("simple_product_1_uenc", simpleList.get("uenc")); -number1 = (int)(${rv2} * props.get("simple_products_list").size()); +number1 = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number1); vars.put("simple_product_2_url_key", simpleList.get("url_key")); vars.put("simple_product_2_name", simpleList.get("title")); vars.put("simple_product_2_id", simpleList.get("id")); vars.put("simple_product_2_uenc", simpleList.get("uenc")); -number = (int)(${rv3} * props.get("configurable_products_list").size()); +number = props.get("RandomObject").nextInt(props.get("configurable_products_list").size()); configurableList = props.get("configurable_products_list").get(number); vars.put("configurable_product_1_url_key", configurableList.get("url_key")); vars.put("configurable_product_1_name", configurableList.get("title")); @@ -3283,7 +3677,7 @@ vars.put("configurable_attribute_id", configurableList.get("attribute_id")); vars.put("configurable_option_id", configurableList.get("attribute_option_id")); vars.put("configurable_product_1_uenc", simpleList.get("uenc")); -number = (int)(Math.random() * props.get("category_url_keys_list").size()); +number = props.get("RandomObject").nextInt(props.get("category_url_keys_list").size()); vars.put("category_url_key", props.get("category_url_keys_list").get(number)); vars.put("category_name", props.get("category_names_list").get(number)); vars.put("testLabel", "GuestChkt"); @@ -3302,7 +3696,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path} GET @@ -3369,7 +3763,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}page_cache/block/render/ GET @@ -3428,7 +3822,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${category_url_key}${url_suffix} GET @@ -3486,7 +3880,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${simple_product_1_url_key}${url_suffix} GET @@ -3508,6 +3902,56 @@ vars.put("loadType", "Guest"); 2 + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + @@ -3553,7 +3997,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -3607,7 +4051,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -3644,27 +4088,78 @@ vars.put("loadType", "Guest"); Assertion.response_data false - 6 + 6 + + + + + \"summary_count\":1 + + Assertion.response_data + false + 2 + + + + + + ${think_time_delay_offset} + ${think_time_deviation} + + + + + + + + + + + + ${request_protocol} + + ${base_path}${simple_product_2_url_key}${url_suffix} + GET + true + false + true + false + false + + + + + + <title>${simple_product_2_name} + <span>In stock</span> + + Assertion.response_data + false + 2 - + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + - \"summary_count\":1 + ^\d+$ Assertion.response_data false - 2 + 1 + variable + product_id - - - ${think_time_delay_offset} - ${think_time_deviation} - - - - + @@ -3672,9 +4167,9 @@ vars.put("loadType", "Guest"); - + ${request_protocol} - ${base_path}${simple_product_2_url_key}${url_suffix} + ${base_path}review/product/listAjax/id/${product_id}/ GET true false @@ -3686,10 +4181,9 @@ vars.put("loadType", "Guest"); - <title>${simple_product_2_name} - <span>In stock</span> + 200 - Assertion.response_data + Assertion.response_code false 2 @@ -3739,7 +4233,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -3795,7 +4289,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -3860,7 +4354,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}${configurable_product_1_url_key}${url_suffix} GET @@ -3882,7 +4376,17 @@ vars.put("loadType", "Guest"); 2 - + + + false + configurable_product_sku + itemprop="sku">([^<]*)<\/ + $1$ + NOT_FOUND + 1 + + + ${think_time_delay_offset} @@ -3890,6 +4394,119 @@ vars.put("loadType", "Guest"); + + true + 1 + + + + + + Content-Type + application/json + + + Accept + */* + + + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/configurable-products/${configurable_product_sku}/options/all + GET + true + false + true + false + false + + + + + attribute_ids + $.[*].attribute_id + NO_VALUE + + BODY + + + + option_values + $.[*].values[0].value_index + NO_VALUE + + BODY + + + + + @@ -3934,7 +4551,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -3955,7 +4572,37 @@ vars.put("loadType", "Guest"); - + + + false + + + + try { + attribute_ids = vars.get("attribute_ids"); + option_values = vars.get("option_values"); + attribute_ids = attribute_ids.replace("[","").replace("]","").replace("\"", ""); + option_values = option_values.replace("[","").replace("]","").replace("\"", ""); + attribute_ids_array = attribute_ids.split(","); + option_values_array = option_values.split(","); + args = ctx.getCurrentSampler().getArguments(); + it = args.iterator(); + while (it.hasNext()) { + argument = it.next(); + if (argument.getStringValue().contains("${")) { + args.removeArgument(argument.getName()); + } + } + for (int i = 0; i < attribute_ids_array.length; i++) { + ctx.getCurrentSampler().addArgument("super_attribute[" + attribute_ids_array[i] + "]", option_values_array[i]); + } + } catch (Exception e) { + log.error("eror…", e); + } + + + + @@ -3990,7 +4637,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -4055,7 +4702,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/ GET @@ -4148,7 +4795,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}rest/default/V1/customers/isEmailAvailable POST @@ -4213,7 +4860,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}rest/default/V1/guest-carts/${cart_id}/estimate-shipping-methods POST @@ -4278,7 +4925,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}rest/default/V1/guest-carts/${cart_id}/shipping-information POST @@ -4343,7 +4990,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}rest/default/V1/guest-carts/${cart_id}/payment-information POST @@ -4414,7 +5061,7 @@ vars.put("loadType", "Guest"); - + ${request_protocol} ${base_path}checkout/onepage/success/ GET @@ -4454,55 +5101,25 @@ vars.put("loadType", "Guest"); - - rv1 - '.' - 1 - 999999 - 1 - true - - - - - rv2 - '.' - 1 - 999999 - 2 - true - - - - - rv3 - '.' - 1 - 999999 - 3 - true - - - Passing arguments between threads import org.apache.jmeter.samplers.SampleResult; -number = (int)(${rv1} * props.get("simple_products_list").size()); +number = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number); vars.put("simple_product_1_url_key", simpleList.get("url_key")); vars.put("simple_product_1_name", simpleList.get("title")); vars.put("simple_product_1_id", simpleList.get("id")); vars.put("simple_product_1_uenc", simpleList.get("uenc")); -number1 = (int)(${rv2} * props.get("simple_products_list").size()); +number1 = props.get("RandomObject").nextInt(props.get("simple_products_list").size()); simpleList = props.get("simple_products_list").get(number1); vars.put("simple_product_2_url_key", simpleList.get("url_key")); vars.put("simple_product_2_name", simpleList.get("title")); vars.put("simple_product_2_id", simpleList.get("id")); vars.put("simple_product_2_uenc", simpleList.get("uenc")); -number = (int)(${rv3} * props.get("configurable_products_list").size()); +number = props.get("RandomObject").nextInt(props.get("configurable_products_list").size()); configurableList = props.get("configurable_products_list").get(number); vars.put("configurable_product_1_url_key", configurableList.get("url_key")); vars.put("configurable_product_1_name", configurableList.get("title")); @@ -4511,7 +5128,7 @@ vars.put("configurable_attribute_id", configurableList.get("attribute_id")); vars.put("configurable_option_id", configurableList.get("attribute_option_id")); vars.put("configurable_product_1_uenc", simpleList.get("uenc")); -number = (int)(Math.random() * props.get("category_url_keys_list").size()); +number = props.get("RandomObject").nextInt(props.get("category_url_keys_list").size()); vars.put("category_url_key", props.get("category_url_keys_list").get(number)); vars.put("category_name", props.get("category_names_list").get(number)); @@ -4550,7 +5167,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path} GET @@ -4587,7 +5204,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}customer/account/login/ GET @@ -4654,7 +5271,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}page_cache/block/render/ GET @@ -4742,7 +5359,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}customer/account/loginPost/ POST @@ -4799,7 +5416,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}${category_url_key}${url_suffix} GET @@ -4857,7 +5474,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}${simple_product_1_url_key}${url_suffix} GET @@ -4879,6 +5496,56 @@ vars.put("loadType", "Customer"); 2 + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + @@ -4924,7 +5591,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -4978,7 +5645,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -5043,7 +5710,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}${simple_product_2_url_key}${url_suffix} GET @@ -5065,6 +5732,56 @@ vars.put("loadType", "Customer"); 2 + + + product_id + .//input[@type="hidden" and @name="product"]/@value + false + true + false + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + product_id + + + + + + + + + + + + ${request_protocol} + + ${base_path}review/product/listAjax/id/${product_id}/ + GET + true + false + true + false + false + + + + + + 200 + + Assertion.response_code + false + 2 + + @@ -5110,7 +5827,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -5166,7 +5883,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -5231,7 +5948,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}${configurable_product_1_url_key}${url_suffix} GET @@ -5253,7 +5970,17 @@ vars.put("loadType", "Customer"); 2 - + + + false + configurable_product_sku + itemprop="sku">([^<]*)<\/ + $1$ + NOT_FOUND + 1 + + + ${think_time_delay_offset} @@ -5261,6 +5988,119 @@ vars.put("loadType", "Customer"); + + true + 1 + + + + + + Content-Type + application/json + + + Accept + */* + + + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/configurable-products/${configurable_product_sku}/options/all + GET + true + false + true + false + false + + + + + attribute_ids + $.[*].attribute_id + NO_VALUE + + BODY + + + + option_values + $.[*].values[0].value_index + NO_VALUE + + BODY + + + + + @@ -5305,7 +6145,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}checkout/cart/add/ POST @@ -5326,7 +6166,37 @@ vars.put("loadType", "Customer"); - + + + false + + + + try { + attribute_ids = vars.get("attribute_ids"); + option_values = vars.get("option_values"); + attribute_ids = attribute_ids.replace("[","").replace("]","").replace("\"", ""); + option_values = option_values.replace("[","").replace("]","").replace("\"", ""); + attribute_ids_array = attribute_ids.split(","); + option_values_array = option_values.split(","); + args = ctx.getCurrentSampler().getArguments(); + it = args.iterator(); + while (it.hasNext()) { + argument = it.next(); + if (argument.getStringValue().contains("${")) { + args.removeArgument(argument.getName()); + } + } + for (int i = 0; i < attribute_ids_array.length; i++) { + ctx.getCurrentSampler().addArgument("super_attribute[" + attribute_ids_array[i] + "]", option_values_array[i]); + } + } catch (Exception e) { + log.error("eror…", e); + } + + + + @@ -5361,7 +6231,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}customer/section/load/ GET @@ -5426,7 +6296,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}checkout/ GET @@ -5559,7 +6429,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}rest/default/V1/carts/mine/estimate-shipping-methods-by-address-id POST @@ -5624,7 +6494,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}rest/default/V1/carts/mine/shipping-information POST @@ -5689,7 +6559,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}rest/default/V1/carts/mine/payment-information POST @@ -5747,7 +6617,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}checkout/onepage/success/ GET @@ -5829,7 +6699,7 @@ vars.put("loadType", "Customer"); - + ${request_protocol} ${base_path}DeploymentEvent.php POST diff --git a/setup/performance-toolkit/files/downloadable_original.txt b/setup/performance-toolkit/files/downloadable_original.txt new file mode 100644 index 0000000000000..9fbb20e6aa426 --- /dev/null +++ b/setup/performance-toolkit/files/downloadable_original.txt @@ -0,0 +1 @@ +original text \ No newline at end of file diff --git a/setup/performance-toolkit/files/downloadable_sample.txt b/setup/performance-toolkit/files/downloadable_sample.txt new file mode 100644 index 0000000000000..679aa535f6a97 --- /dev/null +++ b/setup/performance-toolkit/files/downloadable_sample.txt @@ -0,0 +1 @@ +sample text \ No newline at end of file diff --git a/setup/performance-toolkit/files/search_terms.csv b/setup/performance-toolkit/files/search_terms.csv new file mode 100644 index 0000000000000..fa0f847d22068 --- /dev/null +++ b/setup/performance-toolkit/files/search_terms.csv @@ -0,0 +1,10 @@ +"searchTerm","priceTo" +"the of and a in to it is to was","1000" +"I for that you he be with on by at","1000" +"have are not this but had they his from she","1000" +"that which or we an were as do been their","1000" +"has would there what will all if can her said","1000" +"who one so up as them some when could him","1000" +"into its then two out time my about did your","1000" +"now me no other only just more these also people","1000" +"know any first see very new may well should like","1000" diff --git a/setup/performance-toolkit/files/search_terms_filter.csv b/setup/performance-toolkit/files/search_terms_filter.csv new file mode 100644 index 0000000000000..0924e8caad56c --- /dev/null +++ b/setup/performance-toolkit/files/search_terms_filter.csv @@ -0,0 +1,10 @@ +"searchTerm","mycolor","mysize" +the of and a in to it is to was,my red,my small +I for that you he be with on by at,my red,my medium +have are not this but had they his from she,my red,my large +that which or we an were as do been their,my green,my small +has would there what will all if can her said,my green,my medium +who one so up as them some when could him,my green,my large +into its then two out time my about did your,my yellow,my small +now me no other only just more these also people,my yellow,my medium +know any first see very new may well should like,my yellow,my large