changing / selecting a value in a dropdown box .. using Geb - groovy

As a Geb Newb, this is confusing. In attempting to click on a combo/dropdown box, I'm getting the following error:
"geb.error.RequiredPageContentNotPresent: The required page content 'pages.ecomm.NewEnrollmentPage -> countrySelected: geb.module.Select' is not present"
1. page looks like this
2. here is my source:
3. test spec code, for selecting dropdown. Error appears to indicate the 'countrySelected' content/element isn't on the page? Or I'm not even on the page?
NewEnrollmentPage.groovy
import geb.Page
import geb.module.Select
class NewEnrollmentPage extends Page {
static url = "/shop/spring/enrollment/start/78867?tagCountry=AN&customerType=D&tagLang=ENU&__checkbox_isPC=true&UNI_TODAY=true&__checkbox_UNI_TODAY=true&clearSession=1"
// "/shop/spring/enrollment/product/landing"
// below for mwebs (non-prod) --->v
//At Checker
static at = {
title == "Enrollment"
}
static content = {
// <navigatorName ><options map> <actual navigator>
CrInitOrdButton(wait: true) { driver.findElement(By.id($("[id='toProductsPage']"))) }
countrySelected { $("#countrySelected").module(Select) }
//Options Map
/* wait : true
* required : false
*
*
*
*/
}
}
test.groovy
class test extends smoke.ecomm.resource.ShopBootStrap {
def "Select Country"() {
given:
at NewEnrollmentPage
when: "select United States for Country"
**countrySelected.value('US')**
.
.
.
}
}

Your selector is incorrect. You are selecting using id of countrySelected but that's the name of your element and its id is actually countries. So you need to change your content definition to either:
countrySelected { $("#countries").module(Select) }
or
countrySelected { $(name: "countrySelected").module(Select) }

Related

How to restrict which files are selectable from WKWebView UI delegate in runOpenPanelWith?

In a webpage I host in a WKWebView I want to allow selecting certain file types to open. For that I wrote a TS function to select files:
/**
* Allows the user to select a local file.
*
* #param contentType Restricts the file selection to specific file types.
* #param multiple If true, allows to select more than a single file.
*
* #returns A promise that resolves to a single file or a list of files.
*/
export const selectFile = (contentType: string, multiple: boolean): Promise<File | File[] | null> =>
new Promise((resolve): void => {
const input = document.createElement("input");
input.type = "file";
input.multiple = multiple;
input.accept = contentType;
document.body.appendChild(input);
input.onchange = (): void => {
const files = input.files ? Array.from(input.files) : null;
if (multiple) {
resolve(files);
} else {
resolve(files ? files[0] : null);
}
};
input.click();
document.body.removeChild(input);
});
As you can see there's a content type that can be specfied. In my WKWebView UI delegate I open a file selection panel:
/**
* Called when the web app requests a local file name.
*/
func webView(_ webView: WKWebView,
runOpenPanelWith parameters: WKOpenPanelParameters,
initiatedByFrame frame: WKFrameInfo,
completionHandler: #escaping ([URL]?) -> Void) {
let panel: NSOpenPanel = NSOpenPanel.init();
panel.allowsMultipleSelection = parameters.allowsMultipleSelection;
panel.canChooseDirectories = parameters.allowsDirectories;
panel.canChooseFiles = true;
panel.resolvesAliases = true;
panel.begin { (result) in
if result == .OK {
completionHandler(panel.urls)
} else {
completionHandler(nil)
}
}
}
However I cannot restrict the selectable files (according to the specified content type, e.g. application/json). The given parameters do not contain any value that would help here. So, how can I pass on the content type to the UI delegate function or otherwise make it aware of the possible file types?

Serenity Cucumber4 Environment URL on Page Objects not working

Why does this not work?
When I run the feature file as "Run as Cucumber Feature" I get an error
java.lang.AssertionError: Undefined default URL for page object PageObject
Page Object
#DefaultUrl("page:register.page")
public class AccountCreationPage extends PageObject {
...
}
Config File (serenity.config)
environments {
local {
webdriver.base.url = "https://localhost"
}
demo {
webdriver.base.url = "https://demo.example.com"
}
prod {
webdriver.base.url = "https://example.com"
}
all {
home.page = "#{webdriver.base.url}"
register.page = "#{webdriver.base.url}/register"
}
}
https://johnfergusonsmart.com/environment-specific-configuration-in-serenity-bdd/
shows the use of #DefaultUrl("page:register.page")
Serenity-Cucumber4. Java. Eclipse.
the config file is required to have default as an entry 🤦
environments {
default {
webdriver.base.url = "https://localhost"
}
...
all {
home.page = "#{webdriver.base.url}"
register.page = "#{webdriver.base.url}/register"
}
}

Parameter not being passed to layout-macro-def

It seems like a parameter is not being passes to a layout-macro-def, and I can't figure out why.
I've read the documentation for layouts / layout macros.
In my layout, I have something like this:
result-view {
match: dailyDeals (this) {
from-property: inventory (inventory) // the param to pass
}
message {
template ("Wow!") {
speech ("#{value(this)}")
}
}
render {
layout {
section {
....
value ("#{value(inventory.item)}" // e.g., a vbox text value
....
layout-macro (myMacro) {param (inventory)}
}
}
}
}
And I have a layout macro like this:
layout-macro-def (myMacro) {
params {
param (inventory) {
type (inventory)
max (Many)
}
}
content {
....
value ("#{value(inventory.item)}" // e.g., a vbox text value
.....
}
}
I can access inventory values from within the layout just fine (e.g., inventory.item.) However, it seems that inventory isn't being passed (or is empty?) when it gets to the macro, because inventory.item won't show up in the layout from myMacro.
What am I missing?
I think you need to add the expression key to the param.
Try this:
render {
layout {
section {
....
value ("#{value(inventory.item)}" // e.g., a vbox text value
....
layout-macro (myMacro) {param (inventory) {expression (inventory)} }
}
}
}

How to add existing attribute to an attribute set programmatically in Magento 2

How can I add some existing attributes to a new attribute set programmatically in Magento 2?
in magento 2, there is color & manufactor attribute already created, but by defaultly this two attribute is not assigned to default attribute set. so, we can do like this. then it will assign this two attribute to default attribute when module installing.
<?php
namespace Vendor\Module\Setup;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class InstallData implements InstallDataInterface
{
private $eavSetupFactory;
private $categorySetupFactory;
public function __construct(EavSetupFactory $eavSetupFactory, \Magento\Catalog\Setup\CategorySetupFactory $categorySetupFactory)
{
$this->eavSetupFactory = $eavSetupFactory;
$this->categorySetupFactory = $categorySetupFactory;
}
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
try {
/**
* #var \Magento\Eav\Setup\EavSetup
*/
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
/**
* #var \Magento\Catalog\Setup\CategorySetup
*/
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
$attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId); // get default attribute set id
$attrGroupId = $categorySetup->getDefaultAttributeGroupId($entityTypeId, $attributeSetId); // get default attribute group id (in my case, it returns id of 'Product Details' group)
$colorAttr = $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'color');
if($colorAttr) {
$eavSetup->addAttributeToGroup(
$entityTypeId,
$attributeSetId,
$attrGroupId,
'color',
null
);
}
$manufacturerAttr = $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'manufacturer');
if($manufacturerAttr) {
$eavSetup->addAttributeToGroup(
$entityTypeId,
$attributeSetId,
$attrGroupId,
'manufacturer',
null
);
}
} catch (NoSuchEntityException $e) {
return;
} catch (\Exception $e) {
return;
}
}

How do I make the has_many selector drag and drop sortable with fuelCMS 1.4?

I have created a model and added the $has_many for selecting multiple products. This is working fine but I am unable to make the selected products sortable by drag and drop. I know this is possible I have seen it. But I am unable to find anything in the documentation that shows how to get this done. Here is my model:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(FUEL_PATH.'models/Base_module_model.php');
/**
* This model handles setting up the form fields for our contact form
*
*/
class Products_category_model extends Base_module_model {
public $required = array('name', 'published');
public $has_many = array('products' => array(FUEL_FOLDER => 'Products_model'));
function __construct()
{
parent::__construct('w_product_categories');
}
/*
This will provide the list of records for display in the Admin Panel
Note how the "excerpt" will display, but truncated
Because we are using some MySQL functions in our select statement,
we pass FALSE in as the second parament to prevent CI auto escaping of fields
*/
function list_items($limit = null, $offset = null, $col = 'name', $order = 'asc', $just_count = false)
{
$this->db->select('id, name, published', FALSE);
$data = parent::list_items($limit, $offset, $col, $order);
return $data;
}
function form_fields($values = array(), $related = array())
{
$fields = parent::form_fields($values, $related);
return $fields;
}
}
class Product_category_model extends Base_module_record {
}
So it is very simple I discovered. I added this in the form fields function:
// Makes the has many drag and drop sortable.
$fields['products']['sorting'] = TRUE;
$fields['products']['after_html'] = "<div style=\"clear:both;font-style:italic\">NOTE: you can sort selected product to your choosing by clicking on the product and then dragging it into the desired placement in the list</div>";

Resources