cumulusci-plus 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cumulusci-plus might be problematic. Click here for more details.
- cumulusci/__about__.py +1 -0
- cumulusci/__init__.py +22 -0
- cumulusci/__main__.py +3 -0
- cumulusci/cli/__init__.py +0 -0
- cumulusci/cli/cci.py +244 -0
- cumulusci/cli/error.py +125 -0
- cumulusci/cli/flow.py +185 -0
- cumulusci/cli/logger.py +72 -0
- cumulusci/cli/org.py +692 -0
- cumulusci/cli/plan.py +181 -0
- cumulusci/cli/project.py +391 -0
- cumulusci/cli/robot.py +116 -0
- cumulusci/cli/runtime.py +190 -0
- cumulusci/cli/service.py +521 -0
- cumulusci/cli/task.py +295 -0
- cumulusci/cli/tests/__init__.py +0 -0
- cumulusci/cli/tests/test_cci.py +545 -0
- cumulusci/cli/tests/test_error.py +170 -0
- cumulusci/cli/tests/test_flow.py +276 -0
- cumulusci/cli/tests/test_logger.py +25 -0
- cumulusci/cli/tests/test_org.py +1438 -0
- cumulusci/cli/tests/test_plan.py +245 -0
- cumulusci/cli/tests/test_project.py +235 -0
- cumulusci/cli/tests/test_robot.py +177 -0
- cumulusci/cli/tests/test_runtime.py +197 -0
- cumulusci/cli/tests/test_service.py +853 -0
- cumulusci/cli/tests/test_task.py +266 -0
- cumulusci/cli/tests/test_ui.py +310 -0
- cumulusci/cli/tests/test_utils.py +122 -0
- cumulusci/cli/tests/utils.py +52 -0
- cumulusci/cli/ui.py +234 -0
- cumulusci/cli/utils.py +150 -0
- cumulusci/conftest.py +181 -0
- cumulusci/core/__init__.py +0 -0
- cumulusci/core/config/BaseConfig.py +5 -0
- cumulusci/core/config/BaseTaskFlowConfig.py +5 -0
- cumulusci/core/config/OrgConfig.py +5 -0
- cumulusci/core/config/ScratchOrgConfig.py +5 -0
- cumulusci/core/config/__init__.py +125 -0
- cumulusci/core/config/base_config.py +111 -0
- cumulusci/core/config/base_task_flow_config.py +82 -0
- cumulusci/core/config/marketing_cloud_service_config.py +83 -0
- cumulusci/core/config/oauth2_service_config.py +17 -0
- cumulusci/core/config/org_config.py +604 -0
- cumulusci/core/config/project_config.py +782 -0
- cumulusci/core/config/scratch_org_config.py +251 -0
- cumulusci/core/config/sfdx_org_config.py +220 -0
- cumulusci/core/config/tests/_test_config_backwards_compatibility.py +33 -0
- cumulusci/core/config/tests/test_config.py +1895 -0
- cumulusci/core/config/tests/test_config_expensive.py +839 -0
- cumulusci/core/config/tests/test_config_util.py +91 -0
- cumulusci/core/config/universal_config.py +88 -0
- cumulusci/core/config/util.py +18 -0
- cumulusci/core/datasets.py +303 -0
- cumulusci/core/debug.py +33 -0
- cumulusci/core/dependencies/__init__.py +55 -0
- cumulusci/core/dependencies/base.py +561 -0
- cumulusci/core/dependencies/dependencies.py +273 -0
- cumulusci/core/dependencies/github.py +177 -0
- cumulusci/core/dependencies/github_resolvers.py +244 -0
- cumulusci/core/dependencies/resolvers.py +580 -0
- cumulusci/core/dependencies/tests/__init__.py +0 -0
- cumulusci/core/dependencies/tests/conftest.py +385 -0
- cumulusci/core/dependencies/tests/test_dependencies.py +950 -0
- cumulusci/core/dependencies/tests/test_github.py +83 -0
- cumulusci/core/dependencies/tests/test_resolvers.py +1027 -0
- cumulusci/core/dependencies/utils.py +13 -0
- cumulusci/core/enums.py +11 -0
- cumulusci/core/exceptions.py +311 -0
- cumulusci/core/flowrunner.py +888 -0
- cumulusci/core/github.py +665 -0
- cumulusci/core/keychain/__init__.py +24 -0
- cumulusci/core/keychain/base_project_keychain.py +441 -0
- cumulusci/core/keychain/encrypted_file_project_keychain.py +945 -0
- cumulusci/core/keychain/environment_project_keychain.py +7 -0
- cumulusci/core/keychain/serialization.py +152 -0
- cumulusci/core/keychain/subprocess_keychain.py +24 -0
- cumulusci/core/keychain/tests/conftest.py +50 -0
- cumulusci/core/keychain/tests/test_base_project_keychain.py +299 -0
- cumulusci/core/keychain/tests/test_encrypted_file_project_keychain.py +1228 -0
- cumulusci/core/metadeploy/__init__.py +0 -0
- cumulusci/core/metadeploy/api.py +88 -0
- cumulusci/core/metadeploy/plans.py +25 -0
- cumulusci/core/metadeploy/tests/test_api.py +276 -0
- cumulusci/core/runtime.py +115 -0
- cumulusci/core/sfdx.py +162 -0
- cumulusci/core/source/__init__.py +16 -0
- cumulusci/core/source/github.py +50 -0
- cumulusci/core/source/local_folder.py +35 -0
- cumulusci/core/source_transforms/__init__.py +0 -0
- cumulusci/core/source_transforms/tests/test_transforms.py +1091 -0
- cumulusci/core/source_transforms/transforms.py +532 -0
- cumulusci/core/tasks.py +404 -0
- cumulusci/core/template_utils.py +59 -0
- cumulusci/core/tests/__init__.py +0 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_e2e.yaml +215 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_extract_standard_objects.yaml +199 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_read_explicit_extract_declaration.yaml +3 -0
- cumulusci/core/tests/fake_remote_repo/cumulusci.yml +32 -0
- cumulusci/core/tests/fake_remote_repo/tasks/directory/example_2.py +6 -0
- cumulusci/core/tests/fake_remote_repo/tasks/example.py +43 -0
- cumulusci/core/tests/fake_remote_repo_2/cumulusci.yml +11 -0
- cumulusci/core/tests/fake_remote_repo_2/tasks/example_3.py +6 -0
- cumulusci/core/tests/test_datasets_e2e.py +386 -0
- cumulusci/core/tests/test_exceptions.py +11 -0
- cumulusci/core/tests/test_flowrunner.py +836 -0
- cumulusci/core/tests/test_github.py +942 -0
- cumulusci/core/tests/test_sfdx.py +138 -0
- cumulusci/core/tests/test_source.py +678 -0
- cumulusci/core/tests/test_tasks.py +262 -0
- cumulusci/core/tests/test_utils.py +141 -0
- cumulusci/core/tests/test_utils_merge_config.py +276 -0
- cumulusci/core/tests/test_versions.py +76 -0
- cumulusci/core/tests/untrusted_repo_child/cumulusci.yml +7 -0
- cumulusci/core/tests/untrusted_repo_child/tasks/untrusted_child.py +6 -0
- cumulusci/core/tests/untrusted_repo_parent/cumulusci.yml +26 -0
- cumulusci/core/tests/untrusted_repo_parent/tasks/untrusted_parent.py +6 -0
- cumulusci/core/tests/utils.py +116 -0
- cumulusci/core/tests/yaml/global.yaml +0 -0
- cumulusci/core/utils.py +402 -0
- cumulusci/core/versions.py +149 -0
- cumulusci/cumulusci.yml +1621 -0
- cumulusci/files/admin_profile.xml +20 -0
- cumulusci/files/delete_excludes.txt +424 -0
- cumulusci/files/templates/project/README.md +12 -0
- cumulusci/files/templates/project/cumulusci.yml +63 -0
- cumulusci/files/templates/project/dot-gitignore +60 -0
- cumulusci/files/templates/project/mapping.yml +45 -0
- cumulusci/files/templates/project/scratch_def.json +25 -0
- cumulusci/oauth/__init__.py +0 -0
- cumulusci/oauth/client.py +400 -0
- cumulusci/oauth/exceptions.py +9 -0
- cumulusci/oauth/salesforce.py +95 -0
- cumulusci/oauth/tests/__init__.py +0 -0
- cumulusci/oauth/tests/cassettes/test_get_device_code.yaml +22 -0
- cumulusci/oauth/tests/cassettes/test_get_device_oauth_token.yaml +74 -0
- cumulusci/oauth/tests/test_client.py +308 -0
- cumulusci/oauth/tests/test_salesforce.py +46 -0
- cumulusci/plugins/__init__.py +3 -0
- cumulusci/plugins/plugin_base.py +93 -0
- cumulusci/plugins/plugin_loader.py +59 -0
- cumulusci/robotframework/CumulusCI.py +340 -0
- cumulusci/robotframework/CumulusCI.robot +7 -0
- cumulusci/robotframework/Performance.py +165 -0
- cumulusci/robotframework/Salesforce.py +936 -0
- cumulusci/robotframework/Salesforce.robot +192 -0
- cumulusci/robotframework/SalesforceAPI.py +416 -0
- cumulusci/robotframework/SalesforcePlaywright.py +220 -0
- cumulusci/robotframework/SalesforcePlaywright.robot +40 -0
- cumulusci/robotframework/__init__.py +2 -0
- cumulusci/robotframework/base_library.py +39 -0
- cumulusci/robotframework/faker_mixin.py +89 -0
- cumulusci/robotframework/form_handlers.py +222 -0
- cumulusci/robotframework/javascript/cci_init.js +34 -0
- cumulusci/robotframework/javascript/cumulusci.js +4 -0
- cumulusci/robotframework/locator_manager.py +197 -0
- cumulusci/robotframework/locators_56.py +88 -0
- cumulusci/robotframework/locators_57.py +5 -0
- cumulusci/robotframework/pageobjects/BasePageObjects.py +433 -0
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +246 -0
- cumulusci/robotframework/pageobjects/PageObjectLibrary.py +45 -0
- cumulusci/robotframework/pageobjects/PageObjects.py +351 -0
- cumulusci/robotframework/pageobjects/__init__.py +12 -0
- cumulusci/robotframework/pageobjects/baseobjects.py +120 -0
- cumulusci/robotframework/perftests/short/collection_perf.robot +105 -0
- cumulusci/robotframework/tests/CustomObjectTestPage.py +10 -0
- cumulusci/robotframework/tests/FooTestPage.py +8 -0
- cumulusci/robotframework/tests/cumulusci/base.robot +40 -0
- cumulusci/robotframework/tests/cumulusci/bulkdata.robot +38 -0
- cumulusci/robotframework/tests/cumulusci/communities.robot +57 -0
- cumulusci/robotframework/tests/cumulusci/datagen.robot +84 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryA.py +24 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryB.py +20 -0
- cumulusci/robotframework/tests/salesforce/TestListener.py +93 -0
- cumulusci/robotframework/tests/salesforce/api.robot +178 -0
- cumulusci/robotframework/tests/salesforce/browsers.robot +143 -0
- cumulusci/robotframework/tests/salesforce/classic.robot +51 -0
- cumulusci/robotframework/tests/salesforce/create_contact.robot +59 -0
- cumulusci/robotframework/tests/salesforce/faker.robot +68 -0
- cumulusci/robotframework/tests/salesforce/forms.robot +172 -0
- cumulusci/robotframework/tests/salesforce/label_locator.robot +244 -0
- cumulusci/robotframework/tests/salesforce/labels.html +33 -0
- cumulusci/robotframework/tests/salesforce/locators.robot +149 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/base_pageobjects.robot +100 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/example_page_object.py +25 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/listing_page.robot +115 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/objectmanager.robot +74 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/pageobjects.robot +171 -0
- cumulusci/robotframework/tests/salesforce/performance.robot +109 -0
- cumulusci/robotframework/tests/salesforce/playwright/javascript_keywords.robot +33 -0
- cumulusci/robotframework/tests/salesforce/playwright/open_test_browser.robot +48 -0
- cumulusci/robotframework/tests/salesforce/playwright/playwright.robot +24 -0
- cumulusci/robotframework/tests/salesforce/playwright/ui.robot +32 -0
- cumulusci/robotframework/tests/salesforce/populate.robot +89 -0
- cumulusci/robotframework/tests/salesforce/test_testlistener.py +37 -0
- cumulusci/robotframework/tests/salesforce/ui.robot +361 -0
- cumulusci/robotframework/tests/test_cumulusci_library.py +304 -0
- cumulusci/robotframework/tests/test_locator_manager.py +158 -0
- cumulusci/robotframework/tests/test_pageobjects.py +291 -0
- cumulusci/robotframework/tests/test_performance.py +38 -0
- cumulusci/robotframework/tests/test_salesforce.py +79 -0
- cumulusci/robotframework/tests/test_salesforce_locators.py +73 -0
- cumulusci/robotframework/tests/test_template_util.py +53 -0
- cumulusci/robotframework/tests/test_utils.py +106 -0
- cumulusci/robotframework/utils.py +283 -0
- cumulusci/salesforce_api/__init__.py +0 -0
- cumulusci/salesforce_api/exceptions.py +23 -0
- cumulusci/salesforce_api/filterable_objects.py +96 -0
- cumulusci/salesforce_api/mc_soap_envelopes.py +89 -0
- cumulusci/salesforce_api/metadata.py +721 -0
- cumulusci/salesforce_api/org_schema.py +571 -0
- cumulusci/salesforce_api/org_schema_models.py +226 -0
- cumulusci/salesforce_api/package_install.py +265 -0
- cumulusci/salesforce_api/package_zip.py +301 -0
- cumulusci/salesforce_api/rest_deploy.py +148 -0
- cumulusci/salesforce_api/retrieve_profile_api.py +301 -0
- cumulusci/salesforce_api/soap_envelopes.py +177 -0
- cumulusci/salesforce_api/tests/__init__.py +0 -0
- cumulusci/salesforce_api/tests/metadata_test_strings.py +24 -0
- cumulusci/salesforce_api/tests/test_metadata.py +1015 -0
- cumulusci/salesforce_api/tests/test_package_install.py +219 -0
- cumulusci/salesforce_api/tests/test_package_zip.py +380 -0
- cumulusci/salesforce_api/tests/test_rest_deploy.py +264 -0
- cumulusci/salesforce_api/tests/test_retrieve_profile_api.py +337 -0
- cumulusci/salesforce_api/tests/test_utils.py +124 -0
- cumulusci/salesforce_api/utils.py +51 -0
- cumulusci/schema/cumulusci.jsonschema.json +782 -0
- cumulusci/tasks/__init__.py +0 -0
- cumulusci/tasks/apex/__init__.py +0 -0
- cumulusci/tasks/apex/anon.py +157 -0
- cumulusci/tasks/apex/batch.py +180 -0
- cumulusci/tasks/apex/testrunner.py +835 -0
- cumulusci/tasks/apex/tests/cassettes/ManualEditTestApexIntegrationTests.test_run_tests__integration_test.yaml +703 -0
- cumulusci/tasks/apex/tests/test_apex_tasks.py +1558 -0
- cumulusci/tasks/base_source_control_task.py +17 -0
- cumulusci/tasks/bulkdata/__init__.py +15 -0
- cumulusci/tasks/bulkdata/base_generate_data_task.py +96 -0
- cumulusci/tasks/bulkdata/dates.py +97 -0
- cumulusci/tasks/bulkdata/delete.py +156 -0
- cumulusci/tasks/bulkdata/extract.py +441 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/calculate_dependencies.py +117 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +123 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/hardcoded_default_declarations.py +49 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +283 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +142 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_synthesize_extract_declarations.py +575 -0
- cumulusci/tasks/bulkdata/factory_utils.py +134 -0
- cumulusci/tasks/bulkdata/generate.py +4 -0
- cumulusci/tasks/bulkdata/generate_and_load_data.py +232 -0
- cumulusci/tasks/bulkdata/generate_and_load_data_from_yaml.py +19 -0
- cumulusci/tasks/bulkdata/generate_from_yaml.py +183 -0
- cumulusci/tasks/bulkdata/generate_mapping.py +434 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/dependency_map.py +169 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/extract_mapping_file_generator.py +45 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/generate_mapping_from_declarations.py +121 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/load_mapping_file_generator.py +127 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_generator_post_processes.py +53 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_transforms.py +139 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_extract_mapping_from_declarations.py +135 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_load_mapping_from_declarations.py +330 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_generator_post_processes.py +60 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_transforms.py +188 -0
- cumulusci/tasks/bulkdata/load.py +1196 -0
- cumulusci/tasks/bulkdata/mapping_parser.py +811 -0
- cumulusci/tasks/bulkdata/query_transformers.py +264 -0
- cumulusci/tasks/bulkdata/select_utils.py +792 -0
- cumulusci/tasks/bulkdata/snowfakery.py +753 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/queue_manager.py +478 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_run_until.py +141 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_working_directory.py +53 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/subtask_configurator.py +64 -0
- cumulusci/tasks/bulkdata/step.py +1242 -0
- cumulusci/tasks/bulkdata/tests/__init__.py +0 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_random_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_annoy_strategy.yaml +123 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy.yaml +313 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy_bulk.yaml +550 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_strategy.yaml +175 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_standard_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__multiple_needed.yaml +69 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__none_needed.yaml +22 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__one_needed.yaml +24 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_snowfakery_query_salesforce.yaml +25 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpdatesIntegrationTests.test_updates_task.yaml +80 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_simple_upsert__rest.yaml +270 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert__rest.yaml +267 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field__rest.yaml +369 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field_rest__duplicate_error.yaml +204 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_fields__bulk.yaml +675 -0
- cumulusci/tasks/bulkdata/tests/dummy_data_factory.py +36 -0
- cumulusci/tasks/bulkdata/tests/integration_test_utils.py +49 -0
- cumulusci/tasks/bulkdata/tests/mapping-oid.yml +87 -0
- cumulusci/tasks/bulkdata/tests/mapping_after.yml +38 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly.yml +34 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_incomplete.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_wrong.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_strategy.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_number.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_strategy.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__non_float.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_missing_priority_fields.yml +22 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_no_priority_fields.yml +18 -0
- cumulusci/tasks/bulkdata/tests/mapping_simple.yml +27 -0
- cumulusci/tasks/bulkdata/tests/mapping_v1.yml +28 -0
- cumulusci/tasks/bulkdata/tests/mapping_v2.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_v3.yml +32 -0
- cumulusci/tasks/bulkdata/tests/mapping_vanilla_sf.yml +69 -0
- cumulusci/tasks/bulkdata/tests/mock_data_factory_without_mapping.py +12 -0
- cumulusci/tasks/bulkdata/tests/person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/person_accounts_minimal.yml +15 -0
- cumulusci/tasks/bulkdata/tests/recordtypes.yml +8 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_2.yml +6 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_with_ispersontype.yml +8 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child/child2.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/gen_npsp_standard_objects.recipe.yml +89 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/include_parent.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/npsp_standard_objects_macros.yml +34 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/options.recipe.yml +6 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/query_snowfakery.recipe.yml +16 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/sf_standard_object_macros.yml +83 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.load.yml +2 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.recipe.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_2.load.yml +5 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.recipe.yml +12 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels_2.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/unique_values.recipe.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert.recipe.yml +23 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_2.recipe.yml +29 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_before.yml +10 -0
- cumulusci/tasks/bulkdata/tests/test_base_generate_data_tasks.py +61 -0
- cumulusci/tasks/bulkdata/tests/test_dates.py +99 -0
- cumulusci/tasks/bulkdata/tests/test_delete.py +404 -0
- cumulusci/tasks/bulkdata/tests/test_extract.py +1311 -0
- cumulusci/tasks/bulkdata/tests/test_factory_utils.py +55 -0
- cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +252 -0
- cumulusci/tasks/bulkdata/tests/test_generate_from_snowfakery_task.py +343 -0
- cumulusci/tasks/bulkdata/tests/test_generatemapping.py +1039 -0
- cumulusci/tasks/bulkdata/tests/test_load.py +3175 -0
- cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +1658 -0
- cumulusci/tasks/bulkdata/tests/test_query_db__joins_self_lookups.yml +12 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups.yml +26 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups_select.yml +48 -0
- cumulusci/tasks/bulkdata/tests/test_select.py +171 -0
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +1057 -0
- cumulusci/tasks/bulkdata/tests/test_snowfakery.py +1153 -0
- cumulusci/tasks/bulkdata/tests/test_step.py +3957 -0
- cumulusci/tasks/bulkdata/tests/test_updates.py +513 -0
- cumulusci/tasks/bulkdata/tests/test_upsert.py +1015 -0
- cumulusci/tasks/bulkdata/tests/test_utils.py +158 -0
- cumulusci/tasks/bulkdata/tests/testdata.db +0 -0
- cumulusci/tasks/bulkdata/tests/update_describe.py +50 -0
- cumulusci/tasks/bulkdata/tests/update_person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/utils.py +114 -0
- cumulusci/tasks/bulkdata/update_data.py +260 -0
- cumulusci/tasks/bulkdata/upsert_utils.py +130 -0
- cumulusci/tasks/bulkdata/utils.py +249 -0
- cumulusci/tasks/command.py +178 -0
- cumulusci/tasks/connectedapp.py +186 -0
- cumulusci/tasks/create_package_version.py +778 -0
- cumulusci/tasks/datadictionary.py +745 -0
- cumulusci/tasks/dx_convert_from.py +26 -0
- cumulusci/tasks/github/__init__.py +17 -0
- cumulusci/tasks/github/base.py +16 -0
- cumulusci/tasks/github/commit_status.py +13 -0
- cumulusci/tasks/github/merge.py +11 -0
- cumulusci/tasks/github/publish.py +11 -0
- cumulusci/tasks/github/pull_request.py +11 -0
- cumulusci/tasks/github/release.py +11 -0
- cumulusci/tasks/github/release_report.py +11 -0
- cumulusci/tasks/github/tag.py +11 -0
- cumulusci/tasks/github/tests/__init__.py +0 -0
- cumulusci/tasks/github/tests/test_util.py +202 -0
- cumulusci/tasks/github/tests/test_vcs_migration.py +44 -0
- cumulusci/tasks/github/tests/util_github_api.py +666 -0
- cumulusci/tasks/github/util.py +252 -0
- cumulusci/tasks/marketing_cloud/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/api.py +188 -0
- cumulusci/tasks/marketing_cloud/base.py +38 -0
- cumulusci/tasks/marketing_cloud/deploy.py +345 -0
- cumulusci/tasks/marketing_cloud/get_user_info.py +40 -0
- cumulusci/tasks/marketing_cloud/mc_constants.py +1 -0
- cumulusci/tasks/marketing_cloud/tests/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/tests/conftest.py +46 -0
- cumulusci/tasks/marketing_cloud/tests/expected-payload.json +110 -0
- cumulusci/tasks/marketing_cloud/tests/test_api.py +97 -0
- cumulusci/tasks/marketing_cloud/tests/test_api_soap_envelopes.py +145 -0
- cumulusci/tasks/marketing_cloud/tests/test_base.py +14 -0
- cumulusci/tasks/marketing_cloud/tests/test_deploy.py +400 -0
- cumulusci/tasks/marketing_cloud/tests/test_get_user_info.py +141 -0
- cumulusci/tasks/marketing_cloud/tests/validation-response.json +39 -0
- cumulusci/tasks/metadata/__init__.py +0 -0
- cumulusci/tasks/metadata/ee_src.py +94 -0
- cumulusci/tasks/metadata/managed_src.py +100 -0
- cumulusci/tasks/metadata/metadata_map.yml +868 -0
- cumulusci/tasks/metadata/modify.py +99 -0
- cumulusci/tasks/metadata/package.py +684 -0
- cumulusci/tasks/metadata/tests/__init__.py +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/.hidden/.keep +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/destructiveChanges.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package_install_uninstall.xml +11 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/reports/namespace__TestFolder/TestReport.report +3 -0
- cumulusci/tasks/metadata/tests/sample_package.xml +9 -0
- cumulusci/tasks/metadata/tests/test_ee_src.py +112 -0
- cumulusci/tasks/metadata/tests/test_managed_src.py +111 -0
- cumulusci/tasks/metadata/tests/test_modify.py +123 -0
- cumulusci/tasks/metadata/tests/test_package.py +476 -0
- cumulusci/tasks/metadata_etl/__init__.py +29 -0
- cumulusci/tasks/metadata_etl/base.py +436 -0
- cumulusci/tasks/metadata_etl/duplicate_rules.py +24 -0
- cumulusci/tasks/metadata_etl/field_sets.py +70 -0
- cumulusci/tasks/metadata_etl/help_text.py +92 -0
- cumulusci/tasks/metadata_etl/layouts.py +550 -0
- cumulusci/tasks/metadata_etl/objects.py +68 -0
- cumulusci/tasks/metadata_etl/permissions.py +167 -0
- cumulusci/tasks/metadata_etl/picklists.py +221 -0
- cumulusci/tasks/metadata_etl/remote_site_settings.py +99 -0
- cumulusci/tasks/metadata_etl/sharing.py +138 -0
- cumulusci/tasks/metadata_etl/tests/test_base.py +512 -0
- cumulusci/tasks/metadata_etl/tests/test_duplicate_rules.py +22 -0
- cumulusci/tasks/metadata_etl/tests/test_field_sets.py +156 -0
- cumulusci/tasks/metadata_etl/tests/test_help_text.py +387 -0
- cumulusci/tasks/metadata_etl/tests/test_ip_ranges.py +85 -0
- cumulusci/tasks/metadata_etl/tests/test_layouts.py +858 -0
- cumulusci/tasks/metadata_etl/tests/test_objects.py +236 -0
- cumulusci/tasks/metadata_etl/tests/test_permissions.py +223 -0
- cumulusci/tasks/metadata_etl/tests/test_picklists.py +547 -0
- cumulusci/tasks/metadata_etl/tests/test_remote_site_settings.py +46 -0
- cumulusci/tasks/metadata_etl/tests/test_sharing.py +333 -0
- cumulusci/tasks/metadata_etl/tests/test_value_sets.py +298 -0
- cumulusci/tasks/metadata_etl/value_sets.py +106 -0
- cumulusci/tasks/metadeploy.py +393 -0
- cumulusci/tasks/metaxml.py +88 -0
- cumulusci/tasks/preflight/__init__.py +0 -0
- cumulusci/tasks/preflight/dataset_load.py +49 -0
- cumulusci/tasks/preflight/licenses.py +86 -0
- cumulusci/tasks/preflight/packages.py +14 -0
- cumulusci/tasks/preflight/permsets.py +23 -0
- cumulusci/tasks/preflight/recordtypes.py +16 -0
- cumulusci/tasks/preflight/retrieve_tasks.py +30 -0
- cumulusci/tasks/preflight/settings.py +77 -0
- cumulusci/tasks/preflight/sobjects.py +202 -0
- cumulusci/tasks/preflight/tests/test_dataset_load.py +85 -0
- cumulusci/tasks/preflight/tests/test_licenses.py +174 -0
- cumulusci/tasks/preflight/tests/test_packages.py +14 -0
- cumulusci/tasks/preflight/tests/test_permset_preflights.py +51 -0
- cumulusci/tasks/preflight/tests/test_recordtypes.py +30 -0
- cumulusci/tasks/preflight/tests/test_retrieve_tasks.py +62 -0
- cumulusci/tasks/preflight/tests/test_settings.py +130 -0
- cumulusci/tasks/preflight/tests/test_sobjects.py +231 -0
- cumulusci/tasks/push/README.md +59 -0
- cumulusci/tasks/push/__init__.py +0 -0
- cumulusci/tasks/push/push_api.py +659 -0
- cumulusci/tasks/push/pushfails.py +136 -0
- cumulusci/tasks/push/tasks.py +476 -0
- cumulusci/tasks/push/tests/conftest.py +263 -0
- cumulusci/tasks/push/tests/test_push_api.py +951 -0
- cumulusci/tasks/push/tests/test_push_tasks.py +659 -0
- cumulusci/tasks/release_notes/README.md +63 -0
- cumulusci/tasks/release_notes/__init__.py +0 -0
- cumulusci/tasks/release_notes/exceptions.py +5 -0
- cumulusci/tasks/release_notes/generator.py +137 -0
- cumulusci/tasks/release_notes/parser.py +232 -0
- cumulusci/tasks/release_notes/provider.py +44 -0
- cumulusci/tasks/release_notes/task.py +300 -0
- cumulusci/tasks/release_notes/tests/__init__.py +0 -0
- cumulusci/tasks/release_notes/tests/change_notes/full/example1.md +17 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/2.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/3.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/single/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/test_generator.py +582 -0
- cumulusci/tasks/release_notes/tests/test_parser.py +867 -0
- cumulusci/tasks/release_notes/tests/test_provider.py +512 -0
- cumulusci/tasks/release_notes/tests/test_task.py +461 -0
- cumulusci/tasks/release_notes/tests/utils.py +153 -0
- cumulusci/tasks/robotframework/__init__.py +3 -0
- cumulusci/tasks/robotframework/debugger/DebugListener.py +100 -0
- cumulusci/tasks/robotframework/debugger/__init__.py +10 -0
- cumulusci/tasks/robotframework/debugger/model.py +87 -0
- cumulusci/tasks/robotframework/debugger/ui.py +259 -0
- cumulusci/tasks/robotframework/libdoc.py +269 -0
- cumulusci/tasks/robotframework/robotframework.py +392 -0
- cumulusci/tasks/robotframework/stylesheet.css +130 -0
- cumulusci/tasks/robotframework/template.html +109 -0
- cumulusci/tasks/robotframework/tests/TestLibrary.py +18 -0
- cumulusci/tasks/robotframework/tests/TestPageObjects.py +31 -0
- cumulusci/tasks/robotframework/tests/TestResource.robot +8 -0
- cumulusci/tasks/robotframework/tests/failing_tests.robot +16 -0
- cumulusci/tasks/robotframework/tests/performance.robot +23 -0
- cumulusci/tasks/robotframework/tests/test_browser_proxies.py +137 -0
- cumulusci/tasks/robotframework/tests/test_debugger.py +360 -0
- cumulusci/tasks/robotframework/tests/test_robot_parallel.py +141 -0
- cumulusci/tasks/robotframework/tests/test_robotframework.py +860 -0
- cumulusci/tasks/salesforce/BaseRetrieveMetadata.py +58 -0
- cumulusci/tasks/salesforce/BaseSalesforceApiTask.py +45 -0
- cumulusci/tasks/salesforce/BaseSalesforceMetadataApiTask.py +18 -0
- cumulusci/tasks/salesforce/BaseSalesforceTask.py +4 -0
- cumulusci/tasks/salesforce/BaseUninstallMetadata.py +41 -0
- cumulusci/tasks/salesforce/CreateCommunity.py +124 -0
- cumulusci/tasks/salesforce/CreatePackage.py +29 -0
- cumulusci/tasks/salesforce/Deploy.py +240 -0
- cumulusci/tasks/salesforce/DeployBundles.py +88 -0
- cumulusci/tasks/salesforce/DescribeMetadataTypes.py +26 -0
- cumulusci/tasks/salesforce/EnsureRecordTypes.py +202 -0
- cumulusci/tasks/salesforce/GetInstalledPackages.py +8 -0
- cumulusci/tasks/salesforce/ListCommunities.py +40 -0
- cumulusci/tasks/salesforce/ListCommunityTemplates.py +19 -0
- cumulusci/tasks/salesforce/PublishCommunity.py +62 -0
- cumulusci/tasks/salesforce/RetrievePackaged.py +41 -0
- cumulusci/tasks/salesforce/RetrieveReportsAndDashboards.py +82 -0
- cumulusci/tasks/salesforce/RetrieveUnpackaged.py +36 -0
- cumulusci/tasks/salesforce/SOQLQuery.py +39 -0
- cumulusci/tasks/salesforce/UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/UninstallLocalBundles.py +28 -0
- cumulusci/tasks/salesforce/UninstallLocalNamespacedBundles.py +58 -0
- cumulusci/tasks/salesforce/UninstallPackage.py +32 -0
- cumulusci/tasks/salesforce/UninstallPackaged.py +56 -0
- cumulusci/tasks/salesforce/UpdateAdminProfile.py +8 -0
- cumulusci/tasks/salesforce/__init__.py +79 -0
- cumulusci/tasks/salesforce/activate_flow.py +74 -0
- cumulusci/tasks/salesforce/check_components.py +324 -0
- cumulusci/tasks/salesforce/composite.py +142 -0
- cumulusci/tasks/salesforce/create_permission_sets.py +35 -0
- cumulusci/tasks/salesforce/custom_settings.py +134 -0
- cumulusci/tasks/salesforce/custom_settings_wait.py +132 -0
- cumulusci/tasks/salesforce/enable_prediction.py +107 -0
- cumulusci/tasks/salesforce/insert_record.py +40 -0
- cumulusci/tasks/salesforce/install_package_version.py +242 -0
- cumulusci/tasks/salesforce/license_preflights.py +8 -0
- cumulusci/tasks/salesforce/network_member_group.py +178 -0
- cumulusci/tasks/salesforce/nonsourcetracking.py +228 -0
- cumulusci/tasks/salesforce/org_settings.py +193 -0
- cumulusci/tasks/salesforce/package_upload.py +328 -0
- cumulusci/tasks/salesforce/profiles.py +74 -0
- cumulusci/tasks/salesforce/promote_package_version.py +376 -0
- cumulusci/tasks/salesforce/retrieve_profile.py +195 -0
- cumulusci/tasks/salesforce/salesforce_files.py +244 -0
- cumulusci/tasks/salesforce/sourcetracking.py +507 -0
- cumulusci/tasks/salesforce/tests/__init__.py +3 -0
- cumulusci/tasks/salesforce/tests/test_CreateCommunity.py +278 -0
- cumulusci/tasks/salesforce/tests/test_CreatePackage.py +22 -0
- cumulusci/tasks/salesforce/tests/test_Deploy.py +470 -0
- cumulusci/tasks/salesforce/tests/test_DeployBundles.py +76 -0
- cumulusci/tasks/salesforce/tests/test_EnsureRecordTypes.py +345 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunities.py +84 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunityTemplates.py +49 -0
- cumulusci/tasks/salesforce/tests/test_PackageUpload.py +547 -0
- cumulusci/tasks/salesforce/tests/test_ProfileGrantAllAccess.py +699 -0
- cumulusci/tasks/salesforce/tests/test_PublishCommunity.py +181 -0
- cumulusci/tasks/salesforce/tests/test_RetrievePackaged.py +24 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveReportsAndDashboards.py +56 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveUnpackaged.py +21 -0
- cumulusci/tasks/salesforce/tests/test_SOQLQuery.py +30 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalBundles.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalNamespacedBundles.py +22 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackage.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackaged.py +66 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackagedIncremental.py +127 -0
- cumulusci/tasks/salesforce/tests/test_activate_flow.py +132 -0
- cumulusci/tasks/salesforce/tests/test_base_tasks.py +110 -0
- cumulusci/tasks/salesforce/tests/test_check_components.py +445 -0
- cumulusci/tasks/salesforce/tests/test_composite.py +250 -0
- cumulusci/tasks/salesforce/tests/test_create_permission_sets.py +41 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings.py +227 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings_wait.py +174 -0
- cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py +18 -0
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +240 -0
- cumulusci/tasks/salesforce/tests/test_insert_record.py +110 -0
- cumulusci/tasks/salesforce/tests/test_install_package_version.py +464 -0
- cumulusci/tasks/salesforce/tests/test_network_member_group.py +444 -0
- cumulusci/tasks/salesforce/tests/test_nonsourcetracking.py +235 -0
- cumulusci/tasks/salesforce/tests/test_org_settings.py +407 -0
- cumulusci/tasks/salesforce/tests/test_profiles.py +202 -0
- cumulusci/tasks/salesforce/tests/test_retrieve_profile.py +287 -0
- cumulusci/tasks/salesforce/tests/test_salesforce_files.py +228 -0
- cumulusci/tasks/salesforce/tests/test_sourcetracking.py +350 -0
- cumulusci/tasks/salesforce/tests/test_trigger_handlers.py +300 -0
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +509 -0
- cumulusci/tasks/salesforce/tests/util.py +79 -0
- cumulusci/tasks/salesforce/trigger_handlers.py +119 -0
- cumulusci/tasks/salesforce/uninstall_packaged_incremental.py +136 -0
- cumulusci/tasks/salesforce/update_dependencies.py +290 -0
- cumulusci/tasks/salesforce/update_profile.py +339 -0
- cumulusci/tasks/salesforce/users/permsets.py +227 -0
- cumulusci/tasks/salesforce/users/photos.py +162 -0
- cumulusci/tasks/salesforce/users/tests/photo.mock.txt +1 -0
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +950 -0
- cumulusci/tasks/salesforce/users/tests/test_photos.py +373 -0
- cumulusci/tasks/sample_data/capture_sample_data.py +77 -0
- cumulusci/tasks/sample_data/load_sample_data.py +85 -0
- cumulusci/tasks/sample_data/test_capture_sample_data.py +117 -0
- cumulusci/tasks/sample_data/test_load_sample_data.py +121 -0
- cumulusci/tasks/sfdx.py +83 -0
- cumulusci/tasks/tests/__init__.py +1 -0
- cumulusci/tasks/tests/conftest.py +30 -0
- cumulusci/tasks/tests/test_command.py +129 -0
- cumulusci/tasks/tests/test_connectedapp.py +236 -0
- cumulusci/tasks/tests/test_create_package_version.py +847 -0
- cumulusci/tasks/tests/test_datadictionary.py +1575 -0
- cumulusci/tasks/tests/test_dx_convert_from.py +60 -0
- cumulusci/tasks/tests/test_metadeploy.py +624 -0
- cumulusci/tasks/tests/test_metaxml.py +99 -0
- cumulusci/tasks/tests/test_promote_package_version.py +488 -0
- cumulusci/tasks/tests/test_pushfails.py +96 -0
- cumulusci/tasks/tests/test_salesforce.py +72 -0
- cumulusci/tasks/tests/test_sfdx.py +105 -0
- cumulusci/tasks/tests/test_util.py +207 -0
- cumulusci/tasks/util.py +261 -0
- cumulusci/tasks/vcs/__init__.py +19 -0
- cumulusci/tasks/vcs/commit_status.py +58 -0
- cumulusci/tasks/vcs/create_commit_status.py +37 -0
- cumulusci/tasks/vcs/download_extract.py +199 -0
- cumulusci/tasks/vcs/merge.py +298 -0
- cumulusci/tasks/vcs/publish.py +207 -0
- cumulusci/tasks/vcs/pull_request.py +9 -0
- cumulusci/tasks/vcs/release.py +134 -0
- cumulusci/tasks/vcs/release_report.py +105 -0
- cumulusci/tasks/vcs/tag.py +31 -0
- cumulusci/tasks/vcs/tests/github/test_commit_status.py +196 -0
- cumulusci/tasks/vcs/tests/github/test_download_extract.py +896 -0
- cumulusci/tasks/vcs/tests/github/test_merge.py +1118 -0
- cumulusci/tasks/vcs/tests/github/test_publish.py +823 -0
- cumulusci/tasks/vcs/tests/github/test_pull_request.py +29 -0
- cumulusci/tasks/vcs/tests/github/test_release.py +390 -0
- cumulusci/tasks/vcs/tests/github/test_release_report.py +109 -0
- cumulusci/tasks/vcs/tests/github/test_tag.py +90 -0
- cumulusci/tasks/vlocity/exceptions.py +2 -0
- cumulusci/tasks/vlocity/tests/test_vlocity.py +283 -0
- cumulusci/tasks/vlocity/vlocity.py +342 -0
- cumulusci/tests/__init__.py +1 -0
- cumulusci/tests/cassettes/GET_sobjects_Account_PersonAccount_describe.yaml +18 -0
- cumulusci/tests/cassettes/TestIntegrationInfrastructure.test_integration_tests.yaml +19 -0
- cumulusci/tests/pytest_plugins/pytest_sf_orgconnect.py +307 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr.py +275 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr_serializer.py +160 -0
- cumulusci/tests/pytest_plugins/pytest_typeguard.py +5 -0
- cumulusci/tests/pytest_plugins/test_vcr_string_compressor.py +49 -0
- cumulusci/tests/pytest_plugins/vcr_string_compressor.py +97 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Account_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Case_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Contact_describe.yaml +4838 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Custom__c_describe.yaml +242 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Event_describe.yaml +19 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Global_describe.yaml +1338 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Lead_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_OpportunityContactRole_describe.yaml +34 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Opportunity_describe.yaml +1261 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Organization.yaml +49 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfoList_xml.tpl +15 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfo_xml.tpl +13 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_insert_xml.tpl +24 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_upsert_xml.tpl +25 -0
- cumulusci/tests/test_entry_points.py +20 -0
- cumulusci/tests/test_integration_infrastructure.py +131 -0
- cumulusci/tests/test_main.py +9 -0
- cumulusci/tests/test_schema.py +32 -0
- cumulusci/tests/test_utils.py +657 -0
- cumulusci/tests/test_vcr_serializer.py +134 -0
- cumulusci/tests/uncompressed_cassette.yaml +83 -0
- cumulusci/tests/util.py +344 -0
- cumulusci/utils/__init__.py +731 -0
- cumulusci/utils/classutils.py +9 -0
- cumulusci/utils/collections.py +32 -0
- cumulusci/utils/deprecation.py +11 -0
- cumulusci/utils/encryption.py +31 -0
- cumulusci/utils/fileutils.py +295 -0
- cumulusci/utils/git.py +142 -0
- cumulusci/utils/http/multi_request.py +214 -0
- cumulusci/utils/http/requests_utils.py +103 -0
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +32 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_composite_parallel_salesforce.yaml +65 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_errors.yaml +24 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_reference_ids.yaml +49 -0
- cumulusci/utils/http/tests/test_multi_request.py +255 -0
- cumulusci/utils/iterators.py +21 -0
- cumulusci/utils/logging.py +128 -0
- cumulusci/utils/metaprogramming.py +10 -0
- cumulusci/utils/options.py +138 -0
- cumulusci/utils/parallel/queries_in_parallel/run_queries_in_parallel.py +29 -0
- cumulusci/utils/parallel/queries_in_parallel/tests/test_run_queries_in_parallel.py +50 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +238 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker_queue.py +243 -0
- cumulusci/utils/parallel/task_worker_queues/tests/test_parallel_worker.py +353 -0
- cumulusci/utils/salesforce/count_sobjects.py +46 -0
- cumulusci/utils/salesforce/soql.py +17 -0
- cumulusci/utils/salesforce/tests/cassettes/ManualEdit_TestCountSObjects.test_count_sobjects__network_errors.yaml +23 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects__errors.yaml +33 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects_simple.yaml +29 -0
- cumulusci/utils/salesforce/tests/test_count_sobjects.py +29 -0
- cumulusci/utils/salesforce/tests/test_soql.py +30 -0
- cumulusci/utils/tests/cassettes/ManualEditTestDescribeOrg.test_minimal_schema.yaml +36 -0
- cumulusci/utils/tests/cassettes/ManualEdit_test_describe_to_sql.yaml +191 -0
- cumulusci/utils/tests/test_fileutils.py +284 -0
- cumulusci/utils/tests/test_git.py +85 -0
- cumulusci/utils/tests/test_logging.py +70 -0
- cumulusci/utils/tests/test_option_parsing.py +188 -0
- cumulusci/utils/tests/test_org_schema.py +691 -0
- cumulusci/utils/tests/test_org_schema_models.py +79 -0
- cumulusci/utils/tests/test_waiting.py +25 -0
- cumulusci/utils/version_strings.py +391 -0
- cumulusci/utils/waiting.py +42 -0
- cumulusci/utils/xml/__init__.py +91 -0
- cumulusci/utils/xml/metadata_tree.py +299 -0
- cumulusci/utils/xml/robot_xml.py +114 -0
- cumulusci/utils/xml/salesforce_encoding.py +100 -0
- cumulusci/utils/xml/test/test_metadata_tree.py +251 -0
- cumulusci/utils/xml/test/test_salesforce_encoding.py +173 -0
- cumulusci/utils/yaml/cumulusci_yml.py +401 -0
- cumulusci/utils/yaml/model_parser.py +156 -0
- cumulusci/utils/yaml/safer_loader.py +74 -0
- cumulusci/utils/yaml/tests/bad_cci.yml +5 -0
- cumulusci/utils/yaml/tests/cassettes/TestCumulusciYml.test_validate_url__with_errors.yaml +20 -0
- cumulusci/utils/yaml/tests/test_cumulusci_yml.py +286 -0
- cumulusci/utils/yaml/tests/test_model_parser.py +175 -0
- cumulusci/utils/yaml/tests/test_safer_loader.py +88 -0
- cumulusci/utils/ziputils.py +61 -0
- cumulusci/vcs/base.py +143 -0
- cumulusci/vcs/bootstrap.py +272 -0
- cumulusci/vcs/github/__init__.py +24 -0
- cumulusci/vcs/github/adapter.py +689 -0
- cumulusci/vcs/github/release_notes/generator.py +219 -0
- cumulusci/vcs/github/release_notes/parser.py +151 -0
- cumulusci/vcs/github/release_notes/provider.py +143 -0
- cumulusci/vcs/github/service.py +569 -0
- cumulusci/vcs/github/tests/test_adapter.py +138 -0
- cumulusci/vcs/github/tests/test_service.py +408 -0
- cumulusci/vcs/models.py +586 -0
- cumulusci/vcs/tests/conftest.py +41 -0
- cumulusci/vcs/tests/dummy_service.py +241 -0
- cumulusci/vcs/tests/test_vcs_base.py +687 -0
- cumulusci/vcs/tests/test_vcs_bootstrap.py +727 -0
- cumulusci/vcs/utils/__init__.py +31 -0
- cumulusci/vcs/vcs_source.py +287 -0
- cumulusci_plus-5.0.0.dist-info/METADATA +145 -0
- cumulusci_plus-5.0.0.dist-info/RECORD +744 -0
- cumulusci_plus-5.0.0.dist-info/WHEEL +4 -0
- cumulusci_plus-5.0.0.dist-info/entry_points.txt +3 -0
- cumulusci_plus-5.0.0.dist-info/licenses/AUTHORS.rst +41 -0
- cumulusci_plus-5.0.0.dist-info/licenses/LICENSE +30 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from cumulusci.core import template_utils
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestTemplateUtils:
|
|
5
|
+
def test_string_generator(self):
|
|
6
|
+
x = 100
|
|
7
|
+
y = template_utils.StringGenerator(lambda: str(x))
|
|
8
|
+
assert str(y) == "100"
|
|
9
|
+
x = 200
|
|
10
|
+
assert str(y) == "200"
|
|
11
|
+
|
|
12
|
+
def test_faker_library(self):
|
|
13
|
+
fake = template_utils.FakerTemplateLibrary()
|
|
14
|
+
assert fake.first_name
|
|
15
|
+
assert "example.com" in fake.email(domain="example.com")
|
|
16
|
+
|
|
17
|
+
def test_faker_languages(self):
|
|
18
|
+
fake = template_utils.FakerTemplateLibrary("no_NO")
|
|
19
|
+
assert fake.first_name
|
|
20
|
+
assert "example.com" in fake.email(domain="example.com")
|
|
21
|
+
|
|
22
|
+
def test_format_str(self):
|
|
23
|
+
assert template_utils.format_str("abc") == "abc"
|
|
24
|
+
assert template_utils.format_str("{{abc}}", {"abc": 5}) == "5"
|
|
25
|
+
assert len(template_utils.format_str("{{fake.first_name}}"))
|
|
26
|
+
assert "15" in template_utils.format_str(
|
|
27
|
+
"{{fake.first_name}} {{count}}", {"count": 15}
|
|
28
|
+
)
|
|
29
|
+
assert "15" in template_utils.format_str(
|
|
30
|
+
"{{fake.first_name}} {{count}}", {"count": "15"}
|
|
31
|
+
)
|
|
32
|
+
assert (
|
|
33
|
+
template_utils.format_str("{% raw %}{}{% endraw %}", {"count": "15"})
|
|
34
|
+
== "{}"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def test_format_str_languages(self):
|
|
38
|
+
norwegian_faker = template_utils.FakerTemplateLibrary("no_NO")
|
|
39
|
+
|
|
40
|
+
val = template_utils.format_str(
|
|
41
|
+
"{{vikingfake.first_name}} {{abc}}",
|
|
42
|
+
{"abc": 5, "vikingfake": norwegian_faker},
|
|
43
|
+
)
|
|
44
|
+
assert "5" in val
|
|
45
|
+
|
|
46
|
+
def cosmopolitan_faker(language):
|
|
47
|
+
return template_utils.FakerTemplateLibrary(language)
|
|
48
|
+
|
|
49
|
+
val = template_utils.format_str(
|
|
50
|
+
"{{fakei18n('ne_NP').first_name}} {{abc}}",
|
|
51
|
+
{"abc": 5, "fakei18n": cosmopolitan_faker, "type": type},
|
|
52
|
+
)
|
|
53
|
+
assert "5" in val
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest import mock
|
|
5
|
+
|
|
6
|
+
import cumulusci.robotframework.utils as robot_utils
|
|
7
|
+
from cumulusci.utils import touch
|
|
8
|
+
|
|
9
|
+
mock_SeleniumLibrary = mock.Mock()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MockBuiltIn:
|
|
13
|
+
get_library_instance = mock.Mock(
|
|
14
|
+
return_value={"SeleniumLibrary": mock_SeleniumLibrary}
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
robot_utils.BuiltIn = MockBuiltIn
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestRobotframeworkUtils:
|
|
22
|
+
def setup_method(self):
|
|
23
|
+
mock_SeleniumLibrary.reset_mock()
|
|
24
|
+
|
|
25
|
+
def test_screenshot_decorator_return(self):
|
|
26
|
+
"""Verify that the decorator will return what the decorated function returns"""
|
|
27
|
+
|
|
28
|
+
@robot_utils.capture_screenshot_on_error
|
|
29
|
+
def example_function():
|
|
30
|
+
return "the return value"
|
|
31
|
+
|
|
32
|
+
result = example_function()
|
|
33
|
+
|
|
34
|
+
mock_SeleniumLibrary.capture_page_screenshot.assert_not_called()
|
|
35
|
+
assert result == "the return value"
|
|
36
|
+
|
|
37
|
+
def test_screenshot_decorator_fail(self):
|
|
38
|
+
"""Verify that the decorator will capture a screenshot on keyword failure"""
|
|
39
|
+
|
|
40
|
+
@robot_utils.capture_screenshot_on_error
|
|
41
|
+
def example_function():
|
|
42
|
+
raise Exception("Danger Will Robinson!")
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
example_function()
|
|
46
|
+
except Exception:
|
|
47
|
+
pass
|
|
48
|
+
mock_SeleniumLibrary.capture_page_screenshot.assert_called_once()
|
|
49
|
+
|
|
50
|
+
def test_screenshot_decorator_pass(self):
|
|
51
|
+
"""Verify that decorator does NOT capture screenshot on keyword success"""
|
|
52
|
+
|
|
53
|
+
@robot_utils.capture_screenshot_on_error
|
|
54
|
+
def example_function():
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
example_function()
|
|
58
|
+
|
|
59
|
+
mock_SeleniumLibrary.capture_page_screenshot.assert_not_called()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class TestGetLocatorModule:
|
|
63
|
+
@classmethod
|
|
64
|
+
def setup_class(cls):
|
|
65
|
+
# get_locator_module uses __file__ to locate the locator
|
|
66
|
+
# module. We'll point it to a temporary directory so that
|
|
67
|
+
# we can control what files we test against.
|
|
68
|
+
|
|
69
|
+
cls.tempdir = Path(tempfile.mkdtemp())
|
|
70
|
+
# sorted alphabetically, 5 should come after 40. The
|
|
71
|
+
# code should be sorting numerically so that 5 comes
|
|
72
|
+
# before 40. That's why "locators_5.py" is here.
|
|
73
|
+
touch(Path(cls.tempdir, "locators_5.py"))
|
|
74
|
+
touch(Path(cls.tempdir, "locators_39.py"))
|
|
75
|
+
touch(Path(cls.tempdir, "locators_40.py"))
|
|
76
|
+
|
|
77
|
+
dunder_file = Path(cls.tempdir, "utils.py").absolute()
|
|
78
|
+
cls.patched_utils = mock.patch.object(robot_utils, "__file__", dunder_file)
|
|
79
|
+
cls.patched_utils.start()
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def teardown_class(cls):
|
|
83
|
+
shutil.rmtree(cls.tempdir)
|
|
84
|
+
cls.patched_utils.stop()
|
|
85
|
+
|
|
86
|
+
def test_get_locator_module_name_no_version(self):
|
|
87
|
+
"""Verify that we get the latest version if we don't have a version number"""
|
|
88
|
+
module_name = robot_utils.get_locator_module_name(None)
|
|
89
|
+
assert module_name == "cumulusci.robotframework.locators_40"
|
|
90
|
+
|
|
91
|
+
def test_get_locator_module_name_specific_version(self):
|
|
92
|
+
"""Verify that we get the specific version we ask for"""
|
|
93
|
+
for version in (5, 39, 40):
|
|
94
|
+
actual_module_name = robot_utils.get_locator_module_name(version)
|
|
95
|
+
expected_module_name = f"cumulusci.robotframework.locators_{version}"
|
|
96
|
+
assert expected_module_name == actual_module_name
|
|
97
|
+
|
|
98
|
+
def test_get_locator_module_name_version_too_low(self):
|
|
99
|
+
"""Verify that we get the latest version if version specified isn't supported"""
|
|
100
|
+
module_name = robot_utils.get_locator_module_name(37)
|
|
101
|
+
assert module_name == "cumulusci.robotframework.locators_40"
|
|
102
|
+
|
|
103
|
+
def test_get_locator_module_name_version_too_high(self):
|
|
104
|
+
"""Verify that we get the latest version if version specified isn't supported"""
|
|
105
|
+
module_name = robot_utils.get_locator_module_name(41)
|
|
106
|
+
assert module_name == "cumulusci.robotframework.locators_40"
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import re
|
|
3
|
+
import time
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import robot.api as robot_api
|
|
7
|
+
from robot.libraries.BuiltIn import BuiltIn
|
|
8
|
+
from selenium.common.exceptions import (
|
|
9
|
+
ElementNotInteractableException,
|
|
10
|
+
NoSuchWindowException,
|
|
11
|
+
StaleElementReferenceException,
|
|
12
|
+
WebDriverException,
|
|
13
|
+
)
|
|
14
|
+
from selenium.webdriver.remote.command import Command
|
|
15
|
+
from SeleniumLibrary.errors import ElementNotFound
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def set_pdb_trace(pm=False): # pragma: no cover
|
|
19
|
+
"""Start the Python debugger when robotframework is running.
|
|
20
|
+
|
|
21
|
+
This makes sure that pdb can use stdin/stdout even though
|
|
22
|
+
robotframework has redirected I/O.
|
|
23
|
+
"""
|
|
24
|
+
import pdb
|
|
25
|
+
import sys
|
|
26
|
+
|
|
27
|
+
for attr in ("stdin", "stdout", "stderr"):
|
|
28
|
+
setattr(sys, attr, getattr(sys, "__%s__" % attr))
|
|
29
|
+
if pm:
|
|
30
|
+
# Post-mortem debugging of an exception
|
|
31
|
+
pdb.post_mortem()
|
|
32
|
+
else:
|
|
33
|
+
pdb.set_trace()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# This is a list of user actions that are likely to trigger
|
|
37
|
+
# Aura actions and/or XHRs. We'll add a step to wait for
|
|
38
|
+
# in-flight XHRs to complete after these commands.
|
|
39
|
+
COMMANDS_INVOKING_ACTIONS = {Command.CLICK_ELEMENT}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# This script waits for a) Aura to be available and b)
|
|
43
|
+
# any in-flight Aura XHRs to be complete.
|
|
44
|
+
# We only do this if the page uses Aura, as determined by looking for
|
|
45
|
+
# id="auraAppcacheProgress" in the DOM.
|
|
46
|
+
# It would be nice if we could inject the function when the page loads
|
|
47
|
+
# and then just call it after commands, but I was having trouble
|
|
48
|
+
# getting webdriver to add it to the window scope.
|
|
49
|
+
WAIT_FOR_AURA_SCRIPT = """
|
|
50
|
+
done = arguments[0];
|
|
51
|
+
if (document.getElementById('auraAppcacheProgress')) {
|
|
52
|
+
var waitForXHRs = function() {
|
|
53
|
+
if (window.$A && !window.$A.clientService.inFlightXHRs()) {
|
|
54
|
+
done();
|
|
55
|
+
} else {
|
|
56
|
+
setTimeout(waitForXHRs, 100);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
setTimeout(waitForXHRs, 0);
|
|
60
|
+
} else {
|
|
61
|
+
done();
|
|
62
|
+
}
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
ALWAYS_RETRY_EXCEPTIONS = (
|
|
67
|
+
ElementNotFound,
|
|
68
|
+
ElementNotInteractableException,
|
|
69
|
+
StaleElementReferenceException,
|
|
70
|
+
NoSuchWindowException,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class RetryingSeleniumLibraryMixin(object):
|
|
75
|
+
|
|
76
|
+
debug = False
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def selenium(self):
|
|
80
|
+
selenium = self.builtin.get_library_instance("SeleniumLibrary")
|
|
81
|
+
|
|
82
|
+
# Patch the selenium webdriver to add our own functionality
|
|
83
|
+
# to improve stability.
|
|
84
|
+
if not getattr(selenium.driver, "_cumulus_patched", False):
|
|
85
|
+
orig_execute = selenium.driver.execute
|
|
86
|
+
|
|
87
|
+
def execute(driver_command, params=None):
|
|
88
|
+
try:
|
|
89
|
+
if self.retry_selenium:
|
|
90
|
+
# Retry certain failed commands once
|
|
91
|
+
result = self.selenium_execute_with_retry(
|
|
92
|
+
orig_execute, driver_command, params
|
|
93
|
+
)
|
|
94
|
+
else:
|
|
95
|
+
result = orig_execute(driver_command, params)
|
|
96
|
+
except Exception:
|
|
97
|
+
if driver_command != Command.SCREENSHOT:
|
|
98
|
+
safe_screenshot()
|
|
99
|
+
if self.debug:
|
|
100
|
+
self.selenium.log_source()
|
|
101
|
+
raise
|
|
102
|
+
|
|
103
|
+
# Run the "wait for aura" script after commands that are
|
|
104
|
+
# likely to invoke async actions.
|
|
105
|
+
if driver_command in COMMANDS_INVOKING_ACTIONS:
|
|
106
|
+
self.wait_for_aura()
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
selenium.driver.execute = execute
|
|
110
|
+
selenium.driver._cumulus_patched = True
|
|
111
|
+
|
|
112
|
+
return selenium
|
|
113
|
+
|
|
114
|
+
def selenium_execute_with_retry(self, execute, command, params):
|
|
115
|
+
"""Run a single selenium command and retry once.
|
|
116
|
+
|
|
117
|
+
The retry happens for certain errors that are likely to be resolved
|
|
118
|
+
by retrying.
|
|
119
|
+
"""
|
|
120
|
+
try:
|
|
121
|
+
return execute(command, params)
|
|
122
|
+
except Exception as e:
|
|
123
|
+
if isinstance(e, ALWAYS_RETRY_EXCEPTIONS) or (
|
|
124
|
+
isinstance(e, WebDriverException)
|
|
125
|
+
and "Other element would receive the click" in str(e)
|
|
126
|
+
):
|
|
127
|
+
# Retry
|
|
128
|
+
self.builtin.log("Retrying {} command".format(command), level="WARN")
|
|
129
|
+
time.sleep(2)
|
|
130
|
+
return execute(command, params)
|
|
131
|
+
else:
|
|
132
|
+
raise
|
|
133
|
+
|
|
134
|
+
def wait_for_aura(self):
|
|
135
|
+
"""Run the WAIT_FOR_AURA_SCRIPT.
|
|
136
|
+
|
|
137
|
+
This script polls Aura via $A in Javascript to determine when
|
|
138
|
+
all in-flight XHTTP requests have completed before continuing.
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
self.selenium.driver.execute_async_script(WAIT_FOR_AURA_SCRIPT)
|
|
142
|
+
except Exception:
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def selenium_retry(target=None, retry=True):
|
|
147
|
+
"""Decorator to turn on automatic retries of flaky selenium failures.
|
|
148
|
+
|
|
149
|
+
Decorate a robotframework library class to turn on retries for all
|
|
150
|
+
selenium calls from that library::
|
|
151
|
+
|
|
152
|
+
@selenium_retry
|
|
153
|
+
class MyLibrary(object):
|
|
154
|
+
|
|
155
|
+
# Decorate a method to turn it back off for that method
|
|
156
|
+
@selenium_retry(False)
|
|
157
|
+
def some_keyword(self):
|
|
158
|
+
self.selenium.click_button('foo')
|
|
159
|
+
|
|
160
|
+
Or turn it off by default but turn it on for some methods
|
|
161
|
+
(the class-level decorator is still required)::
|
|
162
|
+
|
|
163
|
+
@selenium_retry(False)
|
|
164
|
+
class MyLibrary(object):
|
|
165
|
+
|
|
166
|
+
@selenium_retry(True)
|
|
167
|
+
def some_keyword(self):
|
|
168
|
+
self.selenium.click_button('foo')
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
if isinstance(target, bool):
|
|
172
|
+
# Decorator was called with a single boolean argument
|
|
173
|
+
retry = target
|
|
174
|
+
target = None
|
|
175
|
+
|
|
176
|
+
def decorate(target):
|
|
177
|
+
if isinstance(target, type):
|
|
178
|
+
cls = target
|
|
179
|
+
# Metaclass time.
|
|
180
|
+
# We're going to generate a new subclass that:
|
|
181
|
+
# a) mixes in RetryingSeleniumLibraryMixin
|
|
182
|
+
# b) sets the initial value of `retry_selenium`
|
|
183
|
+
return type(
|
|
184
|
+
cls.__name__,
|
|
185
|
+
(cls, RetryingSeleniumLibraryMixin),
|
|
186
|
+
{"retry_selenium": retry, "__doc__": cls.__doc__},
|
|
187
|
+
)
|
|
188
|
+
func = target
|
|
189
|
+
|
|
190
|
+
@functools.wraps(func)
|
|
191
|
+
def run_with_retry(self, *args, **kwargs):
|
|
192
|
+
# Set the retry setting and run the original function.
|
|
193
|
+
old_retry = self.retry_selenium
|
|
194
|
+
self.retry = retry
|
|
195
|
+
try:
|
|
196
|
+
return func(self, *args, **kwargs)
|
|
197
|
+
finally:
|
|
198
|
+
# Restore the previous value
|
|
199
|
+
self.retry_selenium = old_retry
|
|
200
|
+
|
|
201
|
+
run_with_retry.is_selenium_retry_decorator = True
|
|
202
|
+
return run_with_retry
|
|
203
|
+
|
|
204
|
+
if target is None:
|
|
205
|
+
# Decorator is being used with arguments
|
|
206
|
+
return decorate
|
|
207
|
+
else:
|
|
208
|
+
# Decorator was used without arguments
|
|
209
|
+
return decorate(target)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def capture_screenshot_on_error(func):
|
|
213
|
+
"""Decorator for capturing a screenshot if a keyword throws an error
|
|
214
|
+
|
|
215
|
+
This decorator will work for both SeleniumLibrary and Browser.
|
|
216
|
+
|
|
217
|
+
If a screenshot cannot be taken for any reason, the screenshot error
|
|
218
|
+
will be logged before the original exception is re-raised.
|
|
219
|
+
|
|
220
|
+
For keywords using the Browser library, this will call the keyword
|
|
221
|
+
"Take screenshot".
|
|
222
|
+
|
|
223
|
+
For keywords using SeleniumLibrary, this decorator will call whatever
|
|
224
|
+
keyword SeleniumLibrary is configured to call on failure. Normally
|
|
225
|
+
that will be "Capture page screenshot".
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
@functools.wraps(func)
|
|
229
|
+
def wrapper(*args, **kwargs):
|
|
230
|
+
try:
|
|
231
|
+
return func(*args, **kwargs)
|
|
232
|
+
except Exception:
|
|
233
|
+
safe_screenshot()
|
|
234
|
+
raise
|
|
235
|
+
|
|
236
|
+
return wrapper
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def safe_screenshot():
|
|
240
|
+
"""Take a screenshot, but log and then ignore errors if the screenshot fails
|
|
241
|
+
|
|
242
|
+
This function should work for both selenium and browser (playwright) libraries
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
libs = BuiltIn().get_library_instance(all=True)
|
|
246
|
+
try:
|
|
247
|
+
if "Browser" in libs:
|
|
248
|
+
libs["Browser"].take_screenshot()
|
|
249
|
+
elif "SeleniumLibrary" in libs:
|
|
250
|
+
libs["SeleniumLibrary"].capture_page_screenshot()
|
|
251
|
+
except Exception as e:
|
|
252
|
+
BuiltIn().log(f"unable to capture screenshot: {e}")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def get_locator_module_name(version):
|
|
256
|
+
"""Return module name of locator file for the specified version
|
|
257
|
+
|
|
258
|
+
If a file for the specified version can't be found, the locator
|
|
259
|
+
file with the highest number will be returned. Passing in None
|
|
260
|
+
effectively means "give me the latest version".
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
here = Path(__file__).parent
|
|
264
|
+
if Path(here, f"locators_{version}.py").exists():
|
|
265
|
+
# our work here is done.
|
|
266
|
+
locator_name = f"locators_{version}"
|
|
267
|
+
else:
|
|
268
|
+
|
|
269
|
+
def by_num(filename):
|
|
270
|
+
"""Pull out the number from a filename, or return zero"""
|
|
271
|
+
nums = re.findall(r"_(\d+)", str(filename))
|
|
272
|
+
if nums:
|
|
273
|
+
return int(nums[-1])
|
|
274
|
+
return 0
|
|
275
|
+
|
|
276
|
+
files = sorted(here.glob("locators_*.py"), key=by_num)
|
|
277
|
+
locator_name = files[-1].stem
|
|
278
|
+
robot_api.logger.warn(
|
|
279
|
+
f"Locators for api {version} not found. Falling back to {locator_name} for salesforce locators"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
locator_module_name = f"cumulusci.robotframework.{locator_name}"
|
|
283
|
+
return locator_module_name
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from cumulusci.core.exceptions import CumulusCIException, CumulusCIFailure
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class MetadataApiError(CumulusCIFailure):
|
|
5
|
+
def __init__(self, message, response):
|
|
6
|
+
super(MetadataApiError, self).__init__(message)
|
|
7
|
+
self.response = response
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MetadataComponentFailure(MetadataApiError):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MetadataParseError(MetadataApiError):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MissingOAuthError(CumulusCIException):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MissingOrgCredentialsError(CumulusCIException):
|
|
23
|
+
pass
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# discovered by trial and error. Usually extended with a list of
|
|
2
|
+
# tooling objects. i.e. any object which is both a tooling object
|
|
3
|
+
# and also a "regular" sobject will be skipped.
|
|
4
|
+
OPT_IN_ONLY = [
|
|
5
|
+
"ApexClass",
|
|
6
|
+
"ApexTrigger",
|
|
7
|
+
"FeedItem",
|
|
8
|
+
"Translation",
|
|
9
|
+
"WebLinkLocalization",
|
|
10
|
+
"RecordTypeLocalization",
|
|
11
|
+
"RecordType",
|
|
12
|
+
"BrandTemplate",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
NOT_COUNTABLE = (
|
|
16
|
+
"ContentDocumentLink", # ContentDocumentLink requires a filter by a single Id on ContentDocumentId or LinkedEntityId
|
|
17
|
+
"ContentFolderItem", # Implementation restriction: ContentFolderItem requires a filter by Id or ParentContentFolderId
|
|
18
|
+
"ContentFolder", # Similar to above
|
|
19
|
+
"ContentFolderLink", # Similar to above
|
|
20
|
+
"ContentFolderMember", # Similar to above
|
|
21
|
+
"IdeaComment", # you must filter using the following syntax: CommunityId = [single ID],
|
|
22
|
+
"Vote", # you must filter using the following syntax: ParentId = [single ID],
|
|
23
|
+
"RecordActionHistory", # Gack: 1133111327-118855 (1126216936)
|
|
24
|
+
"DashboardSnapshotResults", # Gack: 1198622208-46932 (1126216936)
|
|
25
|
+
"RecordRecommendation", # Implementation restriction: RecordRecommendation requires a filter on TargetSobjectType or TargetId or RecordRecommendationId
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
NOT_EXTRACTABLE = NOT_COUNTABLE + (
|
|
30
|
+
"%Share",
|
|
31
|
+
"%Access",
|
|
32
|
+
"%History",
|
|
33
|
+
"%Permission",
|
|
34
|
+
"%PermissionSet",
|
|
35
|
+
"%Permissions",
|
|
36
|
+
"AuthorizationFormDataUse",
|
|
37
|
+
"CustomHelpMenuSection",
|
|
38
|
+
"DataUseLegalBasis",
|
|
39
|
+
"DataUsePurpose",
|
|
40
|
+
"ExternalDataUserAuth",
|
|
41
|
+
"FieldPermissions",
|
|
42
|
+
"Group",
|
|
43
|
+
"GroupMember",
|
|
44
|
+
"PermissionSet",
|
|
45
|
+
"PermissionSetAssignment",
|
|
46
|
+
"PermissionSetGroup",
|
|
47
|
+
"PermissionSetGroupComponent",
|
|
48
|
+
"PermissionSetLicenseAssign",
|
|
49
|
+
"PermissionSetTabSetting",
|
|
50
|
+
"Profile",
|
|
51
|
+
"RecordType",
|
|
52
|
+
"User",
|
|
53
|
+
"UserAppInfo",
|
|
54
|
+
"UserAppMenuCustomization",
|
|
55
|
+
"UserCustomBadge",
|
|
56
|
+
"UserCustomBadgeLocalization",
|
|
57
|
+
"UserEmailPreferredPerson",
|
|
58
|
+
"UserListView",
|
|
59
|
+
"UserListViewCriterion",
|
|
60
|
+
"UserPackageLicense",
|
|
61
|
+
"UserPreference",
|
|
62
|
+
"UserProvAccount",
|
|
63
|
+
"UserProvAccountStaging",
|
|
64
|
+
"UserProvMockTarget",
|
|
65
|
+
"UserProvisioningConfig",
|
|
66
|
+
"UserProvisioningLog",
|
|
67
|
+
"UserProvisioningRequest",
|
|
68
|
+
"UserRole",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Generated with these patterns:
|
|
72
|
+
# "%permission%",
|
|
73
|
+
# "%use%",
|
|
74
|
+
# "%access%",
|
|
75
|
+
# "group",
|
|
76
|
+
# "%share",
|
|
77
|
+
# "NetworkUserHistoryRecent",
|
|
78
|
+
# "ObjectPermissions",
|
|
79
|
+
# "OmniSupervisorConfigUser",
|
|
80
|
+
# "OutgoingEmail",
|
|
81
|
+
# "OutgoingEmailRelation",
|
|
82
|
+
# )
|
|
83
|
+
|
|
84
|
+
# And this code:
|
|
85
|
+
#
|
|
86
|
+
# patterns_to_ignore = NOT_EXTRACTABLE_WITHOUT_NOT_COUNTABLE
|
|
87
|
+
|
|
88
|
+
# names = [obj["name"] for obj in sf.describe()["sobjects"] if obj["createable"]]
|
|
89
|
+
|
|
90
|
+
# regexps_to_ignore = [
|
|
91
|
+
# re.compile(pat.replace("%", ".*"), re.IGNORECASE) for pat in patterns_to_ignore
|
|
92
|
+
# ]
|
|
93
|
+
|
|
94
|
+
# for name in names:
|
|
95
|
+
# if any(reg.match(name) for reg in regexps_to_ignore) and not ("__" in name):
|
|
96
|
+
# print(name)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
CREATE_SUBSCRIBER_ATTRIBUTE = """<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
|
3
|
+
<s:Header>
|
|
4
|
+
<a:Action s:mustUnderstand="1">Configure</a:Action>
|
|
5
|
+
<a:To s:mustUnderstand="1">{soap_instance_url}Service.asmx</a:To>
|
|
6
|
+
<fueloauth>{access_token}</fueloauth>
|
|
7
|
+
</s:Header>
|
|
8
|
+
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
9
|
+
<ConfigureRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI">
|
|
10
|
+
<Options></Options>
|
|
11
|
+
<Action>Create</Action>
|
|
12
|
+
<Configurations>
|
|
13
|
+
<Configuration xsi:type="PropertyDefinition">
|
|
14
|
+
<PartnerKey xsi:nil="true"></PartnerKey>
|
|
15
|
+
<ObjectID xsi:nil="true"></ObjectID>
|
|
16
|
+
<Name>{attribute_name}</Name>
|
|
17
|
+
<PropertyType>string</PropertyType>
|
|
18
|
+
</Configuration>
|
|
19
|
+
</Configurations>
|
|
20
|
+
</ConfigureRequestMsg>
|
|
21
|
+
</s:Body>
|
|
22
|
+
</s:Envelope>"""
|
|
23
|
+
|
|
24
|
+
CREATE_USER = """<?xml version="1.0" encoding="utf-8"?>
|
|
25
|
+
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
|
26
|
+
<s:Header>
|
|
27
|
+
<a:Action s:mustUnderstand="1">Create</a:Action>
|
|
28
|
+
<a:To s:mustUnderstand="1">{soap_instance_url}Service.asmx</a:To>
|
|
29
|
+
<fueloauth>{access_token}</fueloauth>
|
|
30
|
+
</s:Header>
|
|
31
|
+
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
32
|
+
<CreateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI">
|
|
33
|
+
<Objects xsi:type="AccountUser">
|
|
34
|
+
<ObjectID xsi:nil="true"></ObjectID>
|
|
35
|
+
<!-- REQUIRED: specify the MID for Parent BU -->
|
|
36
|
+
<Client>
|
|
37
|
+
<ID>{parent_bu_mid}</ID>
|
|
38
|
+
</Client>
|
|
39
|
+
<!-- REQUIRED: Set MID for BU to use as default (can be same as the parent) -->
|
|
40
|
+
<DefaultBusinessUnit>{default_bu_mid}</DefaultBusinessUnit>
|
|
41
|
+
<!-- Set external key for user -->
|
|
42
|
+
{external_key}
|
|
43
|
+
<!-- Set name of user -->
|
|
44
|
+
{user_name}
|
|
45
|
+
<!-- REQUIRED: Set the user email -->
|
|
46
|
+
<Email>{user_email}</Email>
|
|
47
|
+
<NotificationEmailAddress>{user_email}</NotificationEmailAddress>
|
|
48
|
+
<!-- REQUIRED: Set the user password -->
|
|
49
|
+
<Password>{user_password}</Password>
|
|
50
|
+
<!-- REQUIRED: Set the username -->
|
|
51
|
+
<UserID>{user_username}</UserID>
|
|
52
|
+
<IsAPIUser>true</IsAPIUser>
|
|
53
|
+
{active_flag}
|
|
54
|
+
<IsLocked>false</IsLocked>
|
|
55
|
+
<!-- OPTIONAL: Include this if you want to assign roles to new user -->
|
|
56
|
+
<!-- IDs for system defined roles located here: https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/setting_user_permissions_via_the_web_services_api.htm -->
|
|
57
|
+
{role_id}
|
|
58
|
+
</Objects>
|
|
59
|
+
</CreateRequest>
|
|
60
|
+
</s:Body>
|
|
61
|
+
</s:Envelope>"""
|
|
62
|
+
|
|
63
|
+
UPDATE_USER_ROLE = """<?xml version="1.0" encoding="utf-8"?>
|
|
64
|
+
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
|
65
|
+
<s:Header>
|
|
66
|
+
<a:Action s:mustUnderstand="1">Create</a:Action>
|
|
67
|
+
<a:To s:mustUnderstand="1">{soap_instance_url}Service.asmx</a:To>
|
|
68
|
+
<fueloauth>{access_token}</fueloauth>
|
|
69
|
+
</s:Header>
|
|
70
|
+
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
71
|
+
<UpdateRequest xmlns="http://exacttarget.com/wsdl/partnerAPI">
|
|
72
|
+
<Objects xsi:type="AccountUser">
|
|
73
|
+
<ObjectID xsi:nil="true"></ObjectID>
|
|
74
|
+
<Client>
|
|
75
|
+
<ID>{account_mid}</ID> <!-- Account MID -->
|
|
76
|
+
</Client>
|
|
77
|
+
{external_key} <!-- External key for user to update -->
|
|
78
|
+
<IsAPIUser>true</IsAPIUser>
|
|
79
|
+
{user_name}
|
|
80
|
+
<Email>{user_email}</Email>
|
|
81
|
+
<Password>{user_password}</Password>
|
|
82
|
+
<!-- IDs for system defined roles located here: https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/setting_user_permissions_via_the_web_services_api.htm -->
|
|
83
|
+
<UserPermissions>
|
|
84
|
+
<ID>{role_id}</ID>
|
|
85
|
+
</UserPermissions>
|
|
86
|
+
</Objects>
|
|
87
|
+
</UpdateRequest>
|
|
88
|
+
</s:Body>
|
|
89
|
+
</s:Envelope>"""
|