PromucFlow_constructor/app/client/cypress/support/Pages/PeekOverlay.ts
Anand Srinivasan 73ba3a39c5
feat: peek overlay (#20053)
## Description

Hover over appsmith properties in code to peek data.
<img width="380" alt="image"
src="https://user-images.githubusercontent.com/66776129/217707810-164924c0-36e8-4450-b087-18af333c7547.png">

This right now covers:
- Queries/JsObjects/Apis/Widgets and their properties.
- Note: For query or Api, this'll work only upto `Api.data`. (Not
`Api.data.users[0].id`)
- This is because of the way codemirror renders code and we'll need more
time to see how this is best handled.


Misc:
- added `react-append-to-body` to work with variable height for peek
overlay
- we needed a container that doesn't apply `position: absolute` to
itself
- Because, when a container's `height` is zero with `position: absolute`
(like in bp3-portal), child elements cannot be positioned using just the
`bottom` property
- with `react-append-to-body`, the container won't have `position:
absolute`, instead it is applied to the child element `<div>` directly,
hence we can position using `bottom` property.


Fixes #17507


Media
https://www.loom.com/share/0f17918fcd604805b023c215d57fce43


## Type of change
- New feature (non-breaking change which adds functionality)


## How Has This Been Tested?

- Manual

### Test Plan
https://github.com/appsmithorg/TestSmith/issues/2173
https://github.com/appsmithorg/TestSmith/issues/2178

### Issues raised during DP testing

https://github.com/appsmithorg/appsmith/pull/20053#issuecomment-1420545330

https://github.com/appsmithorg/appsmith/pull/20053#issuecomment-1424427913

## Checklist:
### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


### QA activity:
- [x] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [x] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
2023-02-17 21:33:34 +05:30

108 lines
3.3 KiB
TypeScript

import { ObjectsRegistry } from "../Objects/Registry";
export class PeekOverlay {
private readonly PEEKABLE_ATTRIBUTE = "peek-data";
private readonly locators = {
_overlayContainer: "#t--peek-overlay-container",
_dataContainer: "#t--peek-overlay-data",
_peekableCode: (peekableAttr: string) =>
`[${this.PEEKABLE_ATTRIBUTE}="${peekableAttr}"]`,
// react json viewer selectors
_rjv_variableValue: ".variable-value",
_rjv_topLevelArrayData:
".pushed-content.object-container .object-content .object-key-val",
_rjv_firstLevelBraces:
".pretty-json-container > .object-content:first-of-type > .object-key-val:first-of-type > span",
};
private readonly agHelper = ObjectsRegistry.AggregateHelper;
HoverCode(peekableAttribute: string, visibleText?: string) {
(visibleText
? this.agHelper.GetNAssertContains(
this.locators._peekableCode(peekableAttribute),
visibleText,
)
: this.agHelper.GetElement(this.locators._peekableCode(peekableAttribute))
).realHover();
this.agHelper.Sleep();
}
IsOverlayOpen(checkIsOpen = true) {
checkIsOpen
? this.agHelper.AssertElementExist(this.locators._overlayContainer)
: this.agHelper.AssertElementAbsence(this.locators._overlayContainer);
}
ResetHover() {
this.agHelper.GetElement("body").realHover({ position: "bottomLeft" });
this.agHelper.Sleep();
}
CheckPrimitiveValue(data: string) {
this.agHelper
.GetElement(this.locators._dataContainer)
.children("div")
.should("have.text", data);
}
CheckPrimitveArrayInOverlay(array: Array<string | number>) {
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_variableValue)
.should("have.length", array.length);
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(0)
.contains("[");
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(1)
.contains("]");
}
CheckObjectArrayInOverlay(array: Array<Record<string, any>>) {
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_topLevelArrayData)
.should("have.length", array.length);
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(0)
.contains("[");
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(1)
.contains("]");
}
CheckBasicObjectInOverlay(object: Record<string, string | number>) {
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_variableValue)
.should("have.length", Object.entries(object).length);
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(0)
.contains("{");
this.agHelper
.GetElement(this.locators._dataContainer)
.find(this.locators._rjv_firstLevelBraces)
.eq(1)
.contains("}");
}
VerifyDataType(type: string) {
this.agHelper
.GetElement(this.locators._overlayContainer)
.children("div")
.eq(0)
.should("have.text", type);
}
}