Skip to content

Commit

Permalink
补充表单项组件testid
Browse files Browse the repository at this point in the history
  • Loading branch information
allenve committed Feb 22, 2024
1 parent 51131b6 commit fd040ed
Show file tree
Hide file tree
Showing 48 changed files with 428 additions and 154 deletions.
1 change: 1 addition & 0 deletions examples/components/SchemaRender.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ export default function (schema, schemaProps, showCode, envOverrides) {
};
});
},
enableTestid: true,
...envOverrides
};

Expand Down
8 changes: 5 additions & 3 deletions packages/amis-core/src/SchemaRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,11 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
// 优先使用组件自己的testid或者id,这个解决不了table行内的一些子元素
// 每一行都会出现这个testid的元素,只在测试工具中直接使用nth拿序号
if (props.testid || props.id || props.testIdBuilder == null) {
props.testIdBuilder = new TestIdBuilder(
rest.env.enableTestid ? props.testid || props.id : null
);
if (!(props.testIdBuilder instanceof TestIdBuilder)) {
props.testIdBuilder = new TestIdBuilder(
rest.env.enableTestid ? props.testid || props.id : null
);
}
}

// 自动解析变量模式,主要是方便直接引入第三方组件库,无需为了支持变量封装一层
Expand Down
3 changes: 3 additions & 0 deletions packages/amis-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type {JSONSchema7} from 'json-schema';
import {ListenerAction} from './actions/Action';
import {debounceConfig, trackConfig} from './utils/renderer-event';
import type {TestIdBuilder} from './utils/helper';

export interface Option {
/**
Expand Down Expand Up @@ -689,6 +690,8 @@ export interface BaseSchemaWithoutType {
* 可以组件级别用来关闭移动端样式
*/
useMobileUI?: boolean;

testIdBuilder?: TestIdBuilder;
}

export type OperatorType =
Expand Down
2 changes: 1 addition & 1 deletion packages/amis-core/src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2303,7 +2303,7 @@ export class TestIdBuilder {
}

// 生成子区域的testid生成器
getChild(childPath: string, data?: object) {
getChild(childPath: string | number, data?: object) {
if (this.testId == null) {
return new TestIdBuilder();
}
Expand Down
21 changes: 19 additions & 2 deletions packages/amis-ui/src/components/Breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ClassNamesFn, themeable, ThemeProps} from 'amis-core';
import {RootClose} from 'amis-core';
import {removeHTMLTag} from 'amis-core';
import {Icon} from './icons';
import type {TestIdBuilder} from 'amis-core';

export type ItemPlace = 'start' | 'middle' | 'end';
export type TooltipPositionType = 'top' | 'bottom' | 'left' | 'right';
Expand All @@ -32,13 +33,15 @@ interface BreadcrumbItemProps {
tooltipContainer?: any;
tooltipPosition?: TooltipPositionType;
classnames: ClassNamesFn;
testIdBuilder?: TestIdBuilder;
[propName: string]: any;
}

interface BreadcrumbProps extends ThemeProps {
tooltipContainer?: any;
tooltipPosition?: TooltipPositionType;
items: Array<BreadcrumbBaseItem>;
testIdBuilder?: TestIdBuilder;
[propName: string]: any;
}

Expand All @@ -65,6 +68,7 @@ export class Breadcrumb extends React.Component<BreadcrumbProps> {
separatorClassName,
items,
separator,
testIdBuilder,
...restProps
} = this.props;

Expand All @@ -75,6 +79,9 @@ export class Breadcrumb extends React.Component<BreadcrumbProps> {

const crumbs = items
.map<React.ReactNode>((item, index) => {
const itemTestIdBuilder = testIdBuilder?.getChild(
`item-${item.label || index}`
);
let itemPlace: ItemPlace = 'middle';
if (index === 0) {
itemPlace = 'start';
Expand All @@ -88,6 +95,7 @@ export class Breadcrumb extends React.Component<BreadcrumbProps> {
item={item}
itemPlace={itemPlace}
key={index}
testIdBuilder={itemTestIdBuilder}
></BreadcrumbItem>
);
})
Expand Down Expand Up @@ -157,14 +165,20 @@ export class BreadcrumbItem extends React.Component<
item: BreadcrumbBaseItem,
label?: string
) {
const {itemClassName, dropdownItemClassName, classnames: cx} = this.props;
const {
itemClassName,
dropdownItemClassName,
classnames: cx,
testIdBuilder
} = this.props;
const baseItemClassName =
itemType === 'default' ? itemClassName : dropdownItemClassName;
if (showHref) {
return (
<a
href={item.href}
className={cx('Breadcrumb-item-' + itemType, baseItemClassName)}
{...testIdBuilder?.getTestId()}
>
{item.icon ? (
<Icon
Expand All @@ -179,7 +193,10 @@ export class BreadcrumbItem extends React.Component<
);
}
return (
<span className={cx('Breadcrumb-item-' + itemType, baseItemClassName)}>
<span
className={cx('Breadcrumb-item-' + itemType, baseItemClassName)}
{...testIdBuilder?.getTestId()}
>
{item.icon ? (
<Icon
cx={cx}
Expand Down
9 changes: 7 additions & 2 deletions packages/amis-ui/src/components/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,13 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
readOnly={readOnly}
name={name}
/>
<i />
<span className={cx(labelClassName)}>{children || label}</span>
<i {...testIdBuilder?.getChild('input').getTestId()} />
<span
className={cx(labelClassName)}
{...testIdBuilder?.getChild('label').getTestId()}
>
{children || label}
</span>
{description ? (
<div className={cx('Checkbox-desc')}>{description}</div>
) : null}
Expand Down
20 changes: 17 additions & 3 deletions packages/amis-ui/src/components/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Input from './Input';
import Button from './Button';

import type {Moment} from 'moment';
import type {PlainObject, RendererEnv} from 'amis-core';
import type {PlainObject, RendererEnv, TestIdBuilder} from 'amis-core';
import type {ChangeEventViewMode, MutableUnitOfTime} from './calendar/Calendar';

const availableShortcuts: {[propName: string]: any} = {
Expand Down Expand Up @@ -334,6 +334,7 @@ export interface DateProps extends LocaleProps, ThemeProps {

// 是否为结束时间
isEndDate?: boolean;
testIdBuilder?: TestIdBuilder;

disabledDate?: (date: moment.Moment) => any;
onClick?: (date: moment.Moment) => any;
Expand Down Expand Up @@ -949,6 +950,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
mobileCalendarMode,
label,
env,
testIdBuilder,
onClick,
onMouseEnter,
onMouseLeave,
Expand Down Expand Up @@ -1058,6 +1060,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
testIdBuilder={testIdBuilder?.getChild('calendar')}
/>
</div>
);
Expand All @@ -1081,6 +1084,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
)}
ref={this.domRef}
onClick={this.handleClick}
{...testIdBuilder?.getTestId()}
>
<Input
className={cx('DatePicker-input')}
Expand All @@ -1092,17 +1096,25 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
value={this.state.inputValue || ''}
disabled={disabled}
readOnly={mobileUI}
{...testIdBuilder?.getChild('input').getTestId()}
/>

{clearable &&
!disabled &&
normalizeDate(value, valueFormat || format) ? (
<a className={cx(`DatePicker-clear`)} onClick={this.clearValue}>
<a
className={cx(`DatePicker-clear`)}
onClick={this.clearValue}
{...testIdBuilder?.getChild('clear').getTestId()}
>
<Icon icon="input-clear" className="icon" />
</a>
) : null}

<a className={cx(`DatePicker-toggler`)}>
<a
className={cx(`DatePicker-toggler`)}
{...testIdBuilder?.getChild('toggler').getTestId()}
>
<Icon
icon={viewMode === 'time' ? 'clock' : 'date'}
className="icon"
Expand Down Expand Up @@ -1151,6 +1163,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
testIdBuilder={testIdBuilder?.getChild('calendar')}
// utc={utc}
/>
{isConfirmMode ? (
Expand Down Expand Up @@ -1209,6 +1222,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
testIdBuilder={testIdBuilder?.getChild('calendar')}
// utc={utc}
/>
</PopUp>
Expand Down
6 changes: 5 additions & 1 deletion packages/amis-ui/src/components/ListMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {ThemeProps, themeable} from 'amis-core';
import React from 'react';
import {Options, Option} from 'amis-core';
import {LocaleProps, localeable} from 'amis-core';
import type {TestIdBuilder} from 'amis-core';

export interface ListMenuProps extends ThemeProps, LocaleProps {
options: Options;
Expand All @@ -14,6 +15,7 @@ export interface ListMenuProps extends ThemeProps, LocaleProps {
getItemProps: (props: {item: Option; index: number}) => any;
prefix?: JSX.Element;
children?: React.ReactNode | Array<React.ReactNode>;
testIdBuilder?: TestIdBuilder;
}

interface RenderResult {
Expand All @@ -37,7 +39,8 @@ export class ListMenu extends React.Component<ListMenuProps> {
highlightIndex,
selectedOptions,
mobileUI,
onSelect
onSelect,
testIdBuilder
} = this.props;

if (Array.isArray(option.children) && option.children.length) {
Expand Down Expand Up @@ -74,6 +77,7 @@ export class ListMenu extends React.Component<ListMenuProps> {
)}
key={index}
onClick={onSelect ? (e: any) => onSelect(e, option) : undefined}
{...testIdBuilder?.getChild(option.value || index).getTestId()}
{...getItemProps({
item: option,
index: index
Expand Down
5 changes: 5 additions & 0 deletions packages/amis-ui/src/components/Radios.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {value2array, OptionProps, Option} from './Select';
import chunk from 'lodash/chunk';
import {ClassNamesFn, themeable} from 'amis-core';
import {columnsSplit} from 'amis-core';
import {TestIdBuilder} from 'amis-core';

interface RadioProps extends OptionProps {
id?: string;
Expand All @@ -42,6 +43,7 @@ interface RadioProps extends OptionProps {
classPrefix: string;
classnames: ClassNamesFn;
renderLabel?: (item: Option, props: RadioProps) => JSX.Element;
testIdBuilder?: TestIdBuilder;
}

const defaultLabelRender = (item: Option, props: RadioProps) => (
Expand Down Expand Up @@ -123,8 +125,10 @@ export class Radios extends React.Component<RadioProps, any> {
level,
btnActiveLevel,
classPrefix: ns,
testIdBuilder,
renderLabel = defaultLabelRender
} = this.props;
const itemTestIdBuilder = testIdBuilder?.getChild(option.value || index);

if (optionType === 'button') {
const active = !!~valueArray.indexOf(option);
Expand Down Expand Up @@ -153,6 +157,7 @@ export class Radios extends React.Component<RadioProps, any> {
description={option.description}
inline={inline}
labelClassName={labelClassName}
testIdBuilder={itemTestIdBuilder}
>
{renderLabel(option, this.props)}
</Checkbox>
Expand Down

0 comments on commit fd040ed

Please sign in to comment.